Inverse Attribute in NHibernate
Asked Answered
K

3

93

How do I use the Inverse Attribute? If I am not mistaken, for one to many relationships the inverse attribute must be set to true. For many-to-many relationships, one of the entity class inverse attributes must be set to true and another set to false.

Anyone can shed some lights on this?

Katz answered 3/4, 2009 at 11:58 Comment(1)
You can also check my answer, "When to use inverse="true|false"", on a similar question.Doss
U
130

The inverse attribute must not be set to true ...

You use the inverse attribute to specify the 'owner' of the association. (An association can have only one owner, so one end has to be set to inverse, the other has to be set to 'non inverse'). (Owner: inverse=false; Non-owner: inverse=true)

In a one-to-many association, if you do not mark the collection as the inverse end, then NHibernate will perform an additional UPDATE. In fact, in this case, NHibernate will first insert the entity that is contained in the collection, if necessary insert the entity that owns the collection, and afterwards, updates the 'collection entity', so that the foreign key is set and the association is made. (Note that this also means that the foreign key in your DB should be nullable).

When you mark the collection end as 'inverse', then NHibernate will first persist the entity that 'owns' the collection, and will persist the entities that are in the collection afterwards, avoiding an additional UPDATE statement.

So, in an bi-directional association, you always have one inverse end.

Uranic answered 3/4, 2009 at 12:11 Comment(5)
This explains everything just to add owner is one that has foreign key in tableMitten
In my opinion this is really bad terminology. Why not mark the ownership rather than the 'inverse'?!Map
+1 for using negation on an already negated term :) "The INVERSE attribute MUST NOT be set to true"Typewriting
Good answer, the only question remaining is how to decide who should be the "owner"Owain
What about many-to-many when you have a middle table which holds the relation between 2 entities?Felicle
S
11

In addition to the answer above, and according to my understanding, you need to persist the foreign key value in the collection manually, that is if you don't want the extra update statement:

Parent par = Session.Get<Parent>(8);

Child ch = new Child();
ch.Name = "Emad";

//set the parent foreign key manually
ch.MyParent = par;

par.MyChildren.Add(ch);
Session.Save(par);

for further explanation of the inverse attribute, check the following post:

http://www.emadashi.com/index.php/2008/08/nhibernate-inverse-attribute/

Siret answered 19/6, 2009 at 15:8 Comment(0)
A
3

I can see where the "owner" comes in, but an association is a pipe, and you can look down either end, so whats to say which entity "owns" the pipe.

A different way of looking at this is, that in a One to Many relationships, there are actually 2 relationships going on.

Relationship 1: Parent to Many Children.

Relationship 2: Each Child to a Parent

So NH will attempt to run sql to store each of these in the DB. But it doesn't need to because when you set the Foreign Key e.g. in Relationship 2 when a child is stored, then it automatically has fixed the relationship of a parent to the child as well because Relationship 1 is the "Inverse" of Relationship 2.

So inverse means, its something that we get by default once we've set the main relationship. i.e. there is no need for NH to run sql to fix up Relationship 1 and by marking the children collection as an Inverse NH will skip running sql when the children collection is added to.

I'd assume that if you didn't tell NH it was an inverse, then it would waste effort in doing sql to try and set in place the inverse relationship as well - even though it didn't need to.

Ambrosius answered 14/10, 2011 at 22:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.