Wednesday, July 9, 2008

Understanding the Inverse Attribute on a Many Mapping with Hibernate and JPA Annotations (Java Persistence API)

I actually found this post quite helpful.

JavaRanch Post on Understanding the Inverse Attribute


I am fairly new to hibernate and I've finished the tutorial here (which is great by the way). But I am still confused about the use of the "inverse" property.

My database has a many-to-many bi-directional relationship between zipcodes and notifications. A notification can be sent to many zipcodes, and a zipcode can have many notifications sent to it.

From toying with the code, I can see that if I set one side of the relationship as inverse="true"

code:















than I am unable to add a notification to a zipcode:

code:

Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Notification aNotification = (Notification) session.load(Notification.class, notification_id);
Zipcode aZipcode = (Zipcode) session.load(Zipcode.class, zipcode_id);
aZipcode.getNotificationMappings().add(aNotification);
//nothing happens...no error, or update/insert
session.getTransaction().commit();



I am not sure what this really does for me. If I remove the "inverse" property on both sides (notifications and zip) I can add a zip to a notification, or a notification to a zip - no problem. But if I add the "inverse" property...it seems I am limiting myself, and I don't see the benefit. But according to the tutorial:

quote: The rules you have to remember are straightforward: All bi-directional associations need one side as inverse. In a one-to-many association it has to be the many-side, in many-to-many association you can pick either side, there is no difference.



So my questions are:
1) Do we really need to set one side of the relationship as inverse? My code is working fine (and as desired) without it.
2) If we do set it, what are the advantages? Posts: 182 | Registered: Oct 2004 | IP: Logged
Stevi Deter
ranch hand
Member # 167955

posted Thursday, April 10, 2008 9:58 AM Profile for Stevi Deter Author's Homepage Email Stevi Deter Send New Private Message Edit/Delete Post Reply With Quote James,
An excellent set of questions that really focus on understanding the guts of Hibernate.

What helps me the most is to remember what "inverse" means in this context (which means I look it up in Java Persistence in Hibernate whenever I hit a problem!).

Mapping an association as "inverse" in Hibernate tells the framework that this association is a mirror image of the association on the other side.

When you tell Hibernate a side of an association is inverse=true, you explicitly tell Hibernate *not* to synchronize that end with the database.

This is why, in your example, when you add a notification to your mappings, it doesn't persist the data -- by marking it as inverse="true", you've asked Hibernate to ignore that addition!

The utility is in minimizing/avoiding updates in cases where you want only one end to handle updates, the classic example being adding Bids to an Item in the Caveat Emptor example. You want the Item to handle the cascade of adding and deleting bids; you don't want making a change to Bids to cascade up to the item. This minimizes unnecessary updates, selects, etc.

If the code works fine without inverse, you probably don't need it. If you need to add zipcodes to notifications, and notifications to zip codes, and don't want to force only one method of adding for clarity in your code, don't worry about inverse.

--------------------

There will always be people who are ahead of the curve, and people who are behind the curve. But knowledge moves the curve. --Bill James
Posts: 265 | Registered: Mar 2008 | IP: Logged
Mark Spritzler
ranger/sheriff
Member # 9174

posted Thursday, April 10, 2008 11:17 AM Profile for Mark Spritzler Author's Homepage Edit/Delete Post Reply With Quote

quote:Originally posted by Stevi Deter:
James,
An excellent set of questions that really focus on understanding the guts of Hibernate.

What helps me the most is to remember what "inverse" means in this context (which means I look it up in Java Persistence in Hibernate whenever I hit a problem!).

Mapping an association as "inverse" in Hibernate tells the framework that this association is a mirror image of the association on the other side.

When you tell Hibernate a side of an association is inverse=true, you explicitly tell Hibernate *not* to synchronize that end with the database.

This is why, in your example, when you add a notification to your mappings, it doesn't persist the data -- by marking it as inverse="true", you've asked Hibernate to ignore that addition!

The utility is in minimizing/avoiding updates in cases where you want only one end to handle updates, the classic example being adding Bids to an Item in the Caveat Emptor example. You want the Item to handle the cascade of adding and deleting bids; you don't want making a change to Bids to cascade up to the item. This minimizes unnecessary updates, selects, etc.

If the code works fine without inverse, you probably don't need it. If you need to add zipcodes to notifications, and notifications to zip codes, and don't want to force only one method of adding for clarity in your code, don't worry about inverse.



Sweet answer.

Mark

--------------------

How to Ask Questions the Smart Way FAQ


"I believe you can have both. and sometimes, in order to have both, you need both." - Myself
Posts: 13292 | Registered: Feb 2001 | IP: Logged
sudhan maharjan
greenhorn
Member # 163699

posted Sunday, June 29, 2008 5:16 AM Profile for sudhan maharjan Email sudhan maharjan Send New Private Message Edit/Delete Post Reply With Quote this info might be quite helpful... found it in a book Hibernate Quickly

For a many-to-many bidirectional association, one end of the association must be declared as inverse. The end declared as inverse is significant because the non-inverse end will control the joing table that links the objects. Changes made to the inverse end of the association will not be persisted.

I guess, the relation might work with inverse=true as you have done before if you traced the path through another way... like aNotification.add(aZipcode) because class zipcode has inverse=true. Posts: 1 | Registered: Jan 2008 | IP: Logged
Nirmal Java
greenhorn
Member # 176347

posted Today 3:31 AM Profile for Nirmal Java Email Nirmal Java Send New Private Message Edit/Delete Post Reply With Quote inverse = true ?
================
Replace "inverse" by "ignore" and then see the result:

inverse = true means to ignore the relationship of this side
inverse = false means not to ignore the relationship of this side

In parent-child relationship, parent is one side and children are many side.

one-to-many inverse=”false”
means relationship of parent side should not be ignored. So
parent.getChildren() will be examined, child.getParent() is ignored

For the following example:
Parent parentA = getParentA();
Parent parentB = getParentB();
child = new Child();
parentA.getChildren().add(child); Will be used
child.setParent(parentB); Will be ignored Posts: 1 | Registered: Jul 2008 | IP: Logged

No comments: