Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nhibernate 3.3 one-to-many mapping-by-code updates children instead of inserting

Tags:

c#

nhibernate

I have this one-to-many association I created zilions of times with 'old' nhibernate or fluent. But I cann't make it work with mapping-by-code

These are the classes

 public class Parent
 {
      public virtual IList<Child> Children { get; set; }
 }

 public class Child
 {
      public virtual Parent Parent { get; set; }
 }

Nothing odd

and these are mappings classes

For Parent:

 Bag(x => x.Parent, m => m.Key(k => k.Column("Parent_id")));

Child:

 ManyToOne(x => x.Children, map => { map.Column("Parent_id"); map.Cascade(Cascade.All); });

If I do the following

 var parent = new Parent();
 parent.Children.Add(new Child());

 session.SaveOrUpdate(parent); 

I got correct INSERT for parent, but it does an UPDATE for any child added

UPDATE TableChildren
......
WHERE Id = 0 <-????

What's am I missing? I'm banging my head!!

like image 776
Stefano.net Avatar asked Feb 12 '14 08:02

Stefano.net


1 Answers

I see two issues. The mapping seems to be inverted (Bag should go for Children, ManyToOne for a Parent). The essential setting here is also the inverse="true".

As in detail documented here:

  • Mapping-by-Code - Set and Bag, we should add this:
  • Mapping-by-Code - ManyToOne

The Children should be mapped like this:

Bag(x => x.Children, m => 
    m.Inverse(true);
    m.Cascade(Cascade.All);
    m.Key(k => k.Column("Parent_id")));

And the Parent like this

ManyToOne(x => x.Parent, map => 
{ 
    map.Column("Parent_id"); 
});

The inverse="true" is a way how to instruct NHibernate, that each child can manage itself. So, once the child is added into the Children collection, we also have to set its Parent! NHibernate will then INSERT the child with the correct reference in one step.

like image 196
Radim Köhler Avatar answered Oct 03 '22 10:10

Radim Köhler