3

I have a Parent class with two lists of Child classes

    public class Parent
    {
        ...

        public virtual ICollection<Foo> Foo{ get; set; }

        public virtual ICollection<Bae> Bar{ get; set; }
    }

    public class Foo
    {
        ...

        public virtual Parent Parent{ get; set; }
    }

    public class Bar
    {
        ...

        public virtual Parent Parent{ get; set; }
    }

The mappings are

        public ParentMap()
        {
            ...

            HasMany(m => m.Foo).AsSet().Cascade.All();
            HasMany(m => m.Bar).AsSet().Cascade.All();
        }

        public FooMap()
        {
            ...

            References(m => m.Parent);
        }

        public BarMap()
        {
            ...

            References(m => m.Parent);
        }

Whenever I save the parent object I get

INSERT Parent ...
INSERT Foo with Parent_id set to NULL
INSERT Bar with Parent_id set to NULL
UPDATE Foo set Parent_id to Parent id
UPDATE Bar set Parent_id to Parent id

Is there a way apart from setting the relationship to Inverse to avoid the extra update?

Alexandros B
  • 1,881
  • 1
  • 23
  • 36

2 Answers2

10

If you have a bidirectional assiciation you should set the HasMany side to inverse, this is the most common way.

Another possibility is setting the parent reference to Not.Insert().Not.Update(), then the parent property will be completely ignored for insert/updates.

If you don't need the reference from child to parent just remove it from the class and mapping so you only have the collection.

For the second and third way you can additionally set Not.KeyNullable() on the HasMany, this makes sure that NHibernate inserts the new row with the parent ID already set and avoids the additional update statement (this feature requires NHibernate 3.2.0).

cremor
  • 6,669
  • 1
  • 29
  • 72
  • it makes no sense saving a child in order to save the parent. especially when having two different children objects. what I want is to call `session.Save(parent)` and the whole tree to be saved. – Alexandros B Nov 07 '11 at 12:14
  • @Circadian, That's exactly what inverse will accomplish for you. You don't have to have a child to save the parent. – Cole W Nov 07 '11 at 12:54
  • @Circadian You already have `Cascade.All()`, this will make sure that you don't need to call `Save()` on the childs. This is indepentend of inverse or any other method I suggested. – cremor Nov 07 '11 at 13:08
  • adding `Inverse` to the `HasMany` mappings now executes only the `INSERT` with `Parent_id` set to `NULL` – Alexandros B Nov 07 '11 at 13:30
  • @Circadian Then you didn't set the parent reference to the parent object. You need to make sure that the collections and parent references stay in sync. If you don't want to do that, remove one side. – cremor Nov 07 '11 at 13:37
  • @cremor, in my database the foreign key column is not nullable and Not.KeyNullable() is exactly what I need. I would give you +2 if I could, thanks so much. – knguyen Jan 20 '15 at 19:13
1

AFAIK, not. By setting the inverse property, you specify the owner of the association.

Why is it a problem for you to specify the inverse property ?

Frederik Gheysels
  • 56,135
  • 11
  • 101
  • 154