I have a Parent-Child relationship. Contact is the parent, ContactEndPoint is the child.
I have a method that creates a Contact, adds the ContactEndPoint to it. Everything looks good, Contact.endpoints contains only the new end point and ContactEndPoint.contact references the correct Contact.
I then flush the session and when I check the Contact.endpoints attribute it is empty. Debugging the code reveals that during the flush, Contact.setEndPoints() gets called with an empty Set.
If I then call Session.refresh(Contact) - the Contact.endpoints attribute is again correctly set (1 entry - the ContactEndPoint I created). I can call Session.refresh() in my test case, but in my actual code flushing is handled by an interceptor which does not know which objects need refreshing.
Anyone able to throw some light on this one?
Contact.java
Code:
/**
* @hibernate.class table="contact"
* @hibernate.cache usage="read-write"
*/
public class Contact extends AbstractEntity implements Serializable {
private Set<ContactEndPoint> endpoints;
public Contact() {
this.endpoints = new HashSet<ContactEndPoint>();
}
/**
* @hibernate.one-to-many class="it.orchestrate.oep.contact.ContactEndPoint"
* @hibernate.key column="contactid" not-null="true"
* @hibernate.set inverse="true" cascade="all"
* @return the end points for this contact
*/
public Set<ContactEndPoint> getEndpoints() {
return endpoints;
}
public void setEndpoints(Set<ContactEndPoint> endpoints) {
this.endpoints.clear();
this.endpoints.addAll(endpoints);
}
public void addEndpoint(ContactEndPoint endpoint) {
endpoint.setContact(this);
endpoints.add(endpoint);
}
ContactEndPoint.java
Code:
/**
* @hibernate.class table="contactendpoint"
* @hibernate.cache usage="read-write"
* @synchronization enabled="true"
*/
public class ContactEndPoint extends AbstractEntity implements Serializable {
private Contact contact;
/**
* @hibernate.many-to-one class="it.orchestrate.oep.contact.Contact"
* column="contactid"
* @return the contact associated with this end point
*/
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
}
UpdateCode
Code:
public Contact createContact(Contact c, String mobile) {
Contact contact = contactManager.createContact(c);
ContactEndPoint mobileEndPoint = new ContactEndPoint();
mobileEndPoint.setEndPointValue(mobile);
contact.addEndpoint(mobileEndPoint);
mobileEndPoint = contactManager.createContactEndPoint(mobileEndPoint);
return contact;
(The contactManager.create methods result in session.saveOrUpdate being called on the arguements.)
Contact.hbm.xml
Code:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="contact" name="it.orchestrate.oep.contact.Contact">
<cache usage="read-write"/>
<id type="string" column="id" length="64" name="id">
<generator class="uuid"/>
</id>
<set inverse="true" cascade="all" name="endpoints">
<key column="contactid" not-null="true"/>
<one-to-many class="it.orchestrate.oep.contact.ContactEndPoint"/>
</set>
</class>
</hibernate-mapping>
ContactEndPoint.hbm.xml
Code:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="contactendpoint" name="it.orchestrate.oep.contact.ContactEndPoint">
<cache usage="read-write"/>
<id type="string" column="id" length="64" name="id">
<generator class="uuid"/>
</id>
<many-to-one column="contactid" name="contact" class="it.orchestrate.oep.contact.Contact"/>
</class>
</hibernate-mapping>
thanks, Tom