views:

136

answers:

1

I have a bidirectional relationship in NHibernate:

<class name="Child" table="Children">
  <many-to-one name="Parent" column="ParentId" not-null="true" />
</class>

<class name="Parent">
  <set name="Children" lazy="true" table="Children" cascade="all">
    <key column="ParentId" not-null="true" />
    <one-to-many class="Child" />
  </set>
</class>

How do I save it without setting inverse="true" and setting Parent property on Child?
I do not want to do this because it does not make much sense from the POCO perspective.

Alternatively, is it possible to intercept Add called on NHibernate proxy collection (Children)?
In that case, I would just put the Parent setting logic here.

+1  A: 

Unless you're willing to make the foreign key nullable and accept an insert followed by an update, that's the way bidirectional one-to-many works in NHibernate.

I do have a generic implementation of this pattern that you can use... it's a proof of concept; it can be useful or not, depending on how you look at it, as it kinda breaks the POCO approach, but... well, here it is:

public interface IHaveParent<T>
{
    T Parent { get; set; }
}

public interface IHaveMany<T>
{
    ICollection<T> Children { get; }
}

public static class OneToManyHelper
{
    public static void AddChild<TParent, TChild>(this TParent parent,
                                                 TChild child)
    where TChild : IHaveParent<TParent>
    where TParent : IHaveMany<TChild>
    {
        parent.Children.Add(child);
        child.Parent = parent;
    }
}

With this, you can all AddChild on any parent.

The problem with intercepting Add calls is that you'd always need to instantiate your collections using a special method (which, again, is not POCO).

Diego Mijelshon
Well if I could create a custom collection that sets this on Add/Insert, this would be POCO, since it works this way in most UI frameworks, just for Parent value consistency (not considering saving at all).I could then set it in constructor. But can I? Will NH wrap it in a proxy or will it replace it with a proxy <set>?
Andrey Shchekin
NHibernate always replaces your collections. You can define what types to use, look at http://unhaddins.googlecode.com/svn/trunk/uNhAddIns/uNhAddIns.WPF. However, it seems to me that handling your parent/child relationships there is way more complicated than just setting the parent, adding the usual AddChild method to your parents, or using explicit bidirectional relationships like shown above.
Diego Mijelshon