Differencebetween Cascade & Inverse in Hibernate, What Are They Used For

What is the difference between cascade & inverse in hibernate, what are they used for?

In case of many-to-many relation through intermediary table; "Cascade" says whether a record will be created/updated in the child table. Whereas "Inverse" says whether a record will be created/updated in the intermediary table

e.g. Assume below scenario
1 student can have multiple phones. So Student class has property for Set of phones.
Also 1 Phone can be owned by multiple students. So Phone class has property for Set of Students.
This mapping is mentioned in stud_phone table.

So there are three tables viz. Student, Phone and stud_phone (intermediary) table.
Mapping might look like:

<set name="phoneset" table="stud_phone" cascade="save-update" inverse="true">
<key column="mapping_stud_id">< /key>
<many-to-many class="com.domain.Phone" column="mapping_phon_id"/>
</set>

A new student object is created and 2 new phone objects are added to its set. And session.save(student_obj) is called.
Depending upon "cascade" and "inverse" settings different queries will be fired.

Below are different combinations of cascade and inverse and their impact.

1) CASCADE IS NONE and INVERSE is false

Hibernate: insert into STUDENT (Name, stud_id) values (?, ?)
Hibernate: insert into stud_phone (mapping_stud_id, mapping_phon_id) values (?, ?)
Hibernate: insert into stud_phone (mapping_stud_id, mapping_phon_id) values (?, ?)

2) CASCADE is NONE and INVERSE is true

Hibernate: insert into STUDENT (Name, stud_id) values (?, ?)

3) CASCADE is save-update and INVERSE is false

Hibernate: insert into STUDENT (Name, stud_id) values (?, ?)
Hibernate: insert into phone (phone_num, phone_id) values (?, ?)
Hibernate: insert into phone (phone_num, phone_id) values (?, ?)
Hibernate: insert into stud_phone (mapping_stud_id, mapping_phon_id) values (?, ?)
Hibernate: insert into stud_phone (mapping_stud_id, mapping_phon_id) values (?, ?)

4) CASCADE is save-update and INVERSE true

Hibernate: insert into STUDENT (Name, stud_id) values (?, ?)
Hibernate: insert into phone (phone_num, phone_id) values (?, ?)
Hibernate: insert into phone (phone_num, phone_id) values (?, ?)

As it can be seen, only when CASCADE was save-update the records were created in PHONE table also. Otherwise not.

When INVERSE was false ( i.e. Student was the owner of relationship ) the intermediary table STUD_PHONE was updated. When inverse is true, Phone is owner of relationship, so even though a new student was created, the intermediary table was not updated.

So in case of relation of two entities, "cascade" affects other entity table and "inverse" affects intermediary table. So their effect is independent.

what does inverse and cascade means in NHibernate

I found an explanation when Inverse = false is necessary.
If I want a Parent with collection of "children" and in the child object there won't be
a reference to the parent.

so you do Has many on the parent add inverse = false and not adding the reference in the child.

Hibernate inverse=true saving parent saves children when cascade=all

Let's take an example:

  • one Order has many Lines: OneToMany association
  • Many Lines share one parent Order: ManyToOne association

The owner side is Line. The inverse side is Order.

That means that if you persist an Order, persist a Line, add the line to the collection Order.lines, but don't set Line.order, Hibernate will consider that no association exists between those two entities. Why? Because you only set the inverse side of the association (Order.lines), and not the owner side (Line.order).

Cascade has nothing to do with this. Let's say Order.lines is annotated with cascade=PERSIST. That means that if you create an Order, create a Line, add the Line to Order.lines, and persist the Order, Hibernate will also automatically call persist() on the Line. The Line will thus be persisted without having to explicitely call persist() with this line. But the association between the two entities still won't be saved in the database, because you still haven't set the owner side of the association: Line.order.



Related Topics



Leave a reply



Submit