When to use inverse = false for NHibernate / Hibernate OneToMany relationships?

I am trying to deal with the Hibernate inverse attribute, and it seems to be one of those things that are conceptually difficult.

The bottom line is that when you have a parent (e.g. parent) that has a collection of child objects using one-to-many matching, setting inverse = true for matching tells Hibernate that "the other side (the child) carries responsible for updating itself to maintain a link to a foreign key in its table. "

Doing this seems to have 2 advantages when it comes to adding children to the collection in your code, and then saving the parent (with cascading typing): you save the unnecessary click in the database (since without inverse dialing, Hibernate thinks it has two places for updating relations FK) and in accordance with official documents:

If the association column is declared NOT NULL, NHibernate may cause constraint violations when creating or updating the association. To prevent this problem, you should use bidirectional communication with a multiple-valued end (set or bag) indicated as inverse = "true".

All this seems to make sense so far. What I am not getting is this: when you DO NOT want to use inverse = true for one-to-many relationships?

+69
collections hibernate nhibernate one-to-many inverse
Jun 30 '09 at 0:06
source share
3 answers

According to Mattiu, the only case where you do not want to set inverse = true is where the child does not have the right to be responsible for the update itself, for example, in the case when the child does not know its parent.

Let's try the real world, not a far-fetched example:

<class name="SpyMaster" table="SpyMaster" lazy="true"> <id name="Id"> <generator class="identity"/> </id> <property name="Name"/> <set name="Spies" table="Spy" cascade="save-update"> <key column="SpyMasterId"/> <one-to-many class="Spy"/> </set> </class> <class name="Spy" table="Spy" lazy="true"> <id name="Id"> <generator class="identity"/> </id> <property name="Name"/> </class> 

Spymasters may have spies, but spies never know who their spymaster is because we did not include a one-to-one relationship in the spy class. Also (conveniently) a spy can become a scammer, and therefore he does not need to contact spymaster. We can create objects as follows:

 var sm = new SpyMaster { Name = "Head of Operation Treadstone" }; sm.Spies.Add(new Spy { Name = "Bourne", //SpyMaster = sm // Can't do this }); session.Save(sm); 

In this case, you should set the FK column to zero, since the save action sm will be inserted into the SpyMaster table and Spy table, and only after that it will update the Spy table to set FK. In this case, if we set inverse = true, FK will never be updated.

+81
Jul 01 '09 at 8:02
source share

Despite the highly accepted accepted answer, I have another answer to this question.

Consider a class diagram with these relationships:

 Parent => list of Items
 Item => Parent

No one ever said that the relation Item => Parent is redundant for the relation Parent => Items. An item can refer to any Parent.

But in your application, you know that relationships are redundant . You know that relationships do not need to be stored separately in the database. Thus, you decided to save it in one foreign key , pointing from the element to the parent. This minimal information is enough to create a list and link back.

All you have to do to match this with NH:

  • use the same foreign key for both relationships
  • tell NH that one (list) is redundant for the other and can be ignored when storing an object. (This is what NH actually does with inverse="true" )

These are thoughts that are related to the opposite. Nothing more. This is not a choice; there is only one way to display it correctly.




Spy Problem : This is a completely different discussion if you want to maintain a link from an element to a parent. It depends on your business model, NH does not make any decisions in this. If one of the relations is absent, then, of course, there is no redundancy and there is no use of the opposite.

Misuse: If you use inverse = "true" in a list that does not have redundancy in memory, it just isn't saved. Unless you specify the opposite value = "true" if it should be there, NH may store redundant information twice.

+28
Feb 04 2018-11-11T00: 00Z
source share

If you want to have unidirectional communication, that is, children cannot go to the parent. If so, then the FK column should be NULLABLE, because the children will be saved before the parent.

+14
Jun 30 '09 at 20:57
source share



All Articles