This really confuses me. I am using JPA 1.0, Weblogic 10.3.1.
Say, Parent class has one-to-many relationship with Child class. It is usually set up as Child (owning side) has ManyToOne relationship with Parent.
However, in run-time, we save the Parent and expect all (newly created) children get saved along with it. This is not happening. Is that because Parent is not the owning side? So, I have to save each child and then the parent?
Further, I now use @PrivateOwned (since we are using EclipseLink), now the children are all saved even though Parent is not the owning side. Is @PrivateOwned doing a magic here?
Well, I think I tried but do not remember the outcome.
Assume that works. Then, what is the difference between who is the owning side or not? If either side can cascade any persisit() down to the children, does it even matter who owns the relationship? And why would we care who owns the relationship?
Cascade is useful because it cascades the operation across the relationships. That way you can just call persist once an the whole chain will be persisted. However the owning side is still important. You must manage both sides of the relationship effectively. I usually find it the easiest to do that with some helper methods in the parent. I usually return an unmodifiable collection to force future developers (and myself) not to forget to use them.
It might look something like this:
Joined: Sep 02, 2003
Thanks, but that does not show any difference between the owning side vs. non-owning side. Say, if I define Parent being the owning side vs. Child being the owning side of relationship, would the exact same code work with no change? If it does, then there is no difference who is the owning side; If it does have a difference, what is it?
The owning side does matter. The OneToMany is the non-owning side. This is because the ManyToOne is the table that has the join column.
Take this for example.
In this example suppose I decide to remove one of the employees from the collection on the department object and then flush my transaction. What will happen? The answer is nothing because the ManyToOne is the owning side. I must also set the reference to null from the owning side (employee.setDepartment(null)) now I will see the desired update removing the association in the database. This is because only the owning side of the relationship can update the database as the employee is the table with the join column. It is still important to remove the element from the list though as this keeps my in memory objects in sync with what is going on in the database. In essence it is the developers responsibility to manage the relationships.
Now to your example. If I want to create a department and some employees and persist the department and have it persist the employees with it, I would use cascade. When the persistence provider sees this it will cascade the persist operation across relationships.
for example I make this change:
now instead of having to save the department and then save each employee. I can just create the department and each employee (adding the employees to the list on the department, as well as setting their department reference) and when I am done I just call persist on the department. The cascade rule tells the persistence provider to cascade the persist across the relationship essentially resulting in the same thing as if I had done it all manually.
Joined: Sep 02, 2003
Very clear explanation, thanks so much. Now everything is making sense to me.