• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

JPA persist one-to-many relationship by non-owning side

 
Ranch Hand
Posts: 137
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi there,

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?

Any clarifications will be greatly appreciated.

Thanks,
yan
 
Bartender
Posts: 1682
7
Android Mac OS X IntelliJ IDE Spring Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am not familiar with EclipseLink specific annotations, but have you tried setting cascade rules on the @OneToMany?

i.e.

 
Yan Zhou
Ranch Hand
Posts: 137
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?

Yan
 
Bill Gorder
Bartender
Posts: 1682
7
Android Mac OS X IntelliJ IDE Spring Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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:

 
Yan Zhou
Ranch Hand
Posts: 137
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?

Yan
 
Bill Gorder
Bartender
Posts: 1682
7
Android Mac OS X IntelliJ IDE Spring Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.


 
Yan Zhou
Ranch Hand
Posts: 137
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Very clear explanation, thanks so much. Now everything is making sense to me.

Yan
reply
    Bookmark Topic Watch Topic
  • New Topic