Hi,
Here is my problem description:
1) I am using JPA (EJB3.0) with Hibernate as JPA provider. I am using JDK 1.5, SJAS 9.1, Derby as a database and Hibernate 3.2.2. I am using container managed transactions.
2) I have class Child and class Parent. There is a unidirectional ManyToMany mapping from parent to child as shown below
@Entity
public class Parent implements ... {
....
@ManyToMany(fetch=FetchType.EAGER, targetEntity=Child.class)
@JoinTable(name="PARENT_CHILD",joinColumns=@JoinColumn(name="PARENT_ID"), inverseJoinColumns=@JoinColumn(name="CHILD_ID"))
private Set<Child> children = new HashSet<Child>();
....
// Here is the setter method
public void setChildren(Set<Child> children) {
this.children = children;
}
}
3) First I create a couple of Child objects (first transaction), then I read them from the database (second tx).
After that I create a parent object with an empty children set (third tx), then I read it from the database (fourth tx), then I add the 2 children and the I update the parent (fifth tx).
I do not need any cascading of operations from parent to child.
For the update method, I am using the Hibernate entity manager merge() method.
I expected that the parent object would insert a couple of rows in the join table (since it is the owning side).
BUT to my surprise I found that no data was inserted in the join table!!!
OK, I know that Hibernate will use proxy for the Hashset-collection but that proxy should still be able to detect that the collection has become dirty and update the join table.
The strangest thing is that the merge method returns an entity that is correct (i.e. has 2 children) but if I read it with again (in a new tx with findByPK) then the collection is empty! The error was difficult to find for that reason.
I found a workaround for this problem but it is ugly. It is a change in the set-method, like this
public void setChildren(Set<Child> children) {
if( this.children == null) ;
this.children = new HashSet<Child>();
}
this.children.clear();
this.children.addAll(children);
}
and then everything behaves as expected.
Is this a known problem or I am missing something? Is there a more elegant (more Hibernate transparent) solution?
Regards.
/ Daniel
|