I am going through the hibernate documentation and came across the concept of inverse attribute. I am new to Hibernate so I am feeling difficulty in understanding the concept properly.
http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/collections.html#collections-bidirectional
<class name="Category">
<id name="id" column="CATEGORY_ID"/>
...
<bag name="items" table="CATEGORY_ITEM">
<key column="CATEGORY_ID"/>
<many-to-many class="Item" column="ITEM_ID"/>
</bag>
</class>
<class name="Item">
<id name="id" column="ITEM_ID"/>
...
<!-- inverse end -->
<bag name="categories" table="CATEGORY_ITEM" inverse="true">
<key column="ITEM_ID"/>
<many-to-many class="Category" column="CATEGORY_ID"/>
</bag>
</class>
From above code, the inverse="true"
is applied to categories, so I understood that categories is the inverse end.
But I am seeing some contradiction to my understanding:
Changes made only to the inverse end of the association are not persisted.
category.getItems().add(item); // The category now "knows" about the relationship
item.getCategories().add(category); // The item now "knows" about the relationship
session.persist(item); // The relationship won't be saved!
session.persist(category); // The relationship will be saved
If categories is on inverse end then how the relationship is saved here?
The non-inverse side is used to save the in-memory representation to the database.
After looking at the example and reading above statement I came to know that categories is on non-inverse end.
Please help me in knowing how to interpret this inverse="true"
attribute. After searching in net and looking at answers in SO, I came to know the usefulness of this attribute but still I have this confusion.
inverse="true"
basically means that the inverse relationship is also mapped within the class definition of the other class. But, it's real meaning is that it defines which side is the parent or the relationship owner for the two entities (parent or child). Hence, inverse="true"
in a Hibernate mapping shows that this class (the one with this XML definition) is the relationship owner; while the other class is the child.
If you want to know more about this, then I would definitely have a look at this article: http://www.mkyong.com/hibernate/inverse-true-example-and-explanation/ because it's easy to be misled of the meaning of this attribute in hibernate.
Inverse keyword is created to defines which side is the owner to maintain the relationship. The procedure for updating and inserting varies according to this attribute.
Let's suppose we have two tables:
principal_table, middle_table
with a relationship of one to many. The hiberntate mapping classes are Principal and Middle respectively.
So the Principal class has a SET of Middle objects. The xml mapping file should be like following:
<hibernate-mapping>
<class name="path.to.class.Principal" table="principal_table" ...>
...
<set name="middleObjects" table="middle_table" inverse="true" fetch="select">
<key>
<column name="PRINCIPAL_ID" not-null="true" />
</key>
<one-to-many class="path.to.class.Middel" />
</set>
...
As inverse is set to ”true”, it means “Middle” class is the relationship owner, so Principal class will NOT UPDATE the relationship.
So the procedure for updating could be implemented like this:
session.beginTransaction();
Principal principal = new Principal();
principal.setSomething("1");
principal.setSomethingElse("2");
Middle middleObject = new Middle();
middleObject.setSomething("1");
middleObject.setPrincipal(principal);
principal.getMiddleObjects().add(middleObject);
session.saveOrUpdate(principal);
session.saveOrUpdate(middleObject); // NOTICE: you will need to save it manually
session.getTransaction().commit();
Further information can be found Here It is a well explained tutorial about how to use inverse attribute. It also shows how hinernate translate this into SQL queries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With