0

I have this situation:

public abstract class Node : Entity
{
    public virtual Node Parent { get; set; }

    private ICollection<Node> _children = new HashSet<Node>();
    public virtual ICollection<Node> Children
    {
        get { return _children; }
        set { _children = value; }
    }
}

A node can have a maximum of one parent and several children. I use this mapping file:

public class NodeMap : IAutoMappingOverride<Node>
{
    public void Override(AutoMapping<Node> mapping)
    {
        mapping.HasMany<Node>(x => x.Children)
        .KeyColumn("ParentId")
        .KeyNullable()
        .AsSet()
        .Inverse()
        .Cascade.SaveUpdate()
        .ForeignKeyConstraintName("FK_Node_ParentId")
        .Not.LazyLoad();
    }
}

The connection between nodes is only persisted if I add the parent to the child and the child to the parent. However, I would like to persist 'connections' between nodes if the parent is just added to the child. Can I achieve this with fnh mapping?

PS:

Let me try to specify things a bit clearer. I have 5 nodes (1,2,3,4,5).

There are bi directional connections between these:

Parent <-> Child
1 <-> 2
2 <-> 3
2 <-> 6
3 <-> 4
4 <-> 5

But only a unidirectional connection between 6 and 4, as 4 already has a parent namely 3.

Unfortunately, the connection between 6 and 4 is not persisted. Maybe I have to change the domain model but I was hoping to be able to achieve this ‘mixture of uni/bi directionality’.

Thanks.

PPS:

Saving:

INHibernateRepository<Node> NodeRepository = new NHibernateRepository<Node>();

...

NodeRepository.SaveOrUpdate(Node1); // save topnode
NodeRepository.DbContext.CommitChanges();
cs0815
  • 16,751
  • 45
  • 136
  • 299

1 Answers1

1

By setting Inverse, you are telling NHibernate that the other size (the Parent reference) is the one that maintains the relationship.

If you remove that, you'll be able to persist children added to the parent. Keep in mind that if you don't designate one of the sides as Inverse, you'll have redundant updates.

A better alternative that keeps in-memory consistency is adding a helper method AddChild(Node) that adds the node to the collection and sets its Parent property.


Unrelated: .Not.LazyLoad is a very bad idea, particularly on a hierarchical structure.

Diego Mijelshon
  • 52,548
  • 16
  • 116
  • 154
  • Thanks I'll have a look into this tomorrow. I tried to remove Inverse in the past and it did not work. My object graph is not very big so Not.LazyLoad is ok. – cs0815 Jul 31 '12 at 18:24
  • Sorry removing Inverse does not make any difference. – cs0815 Aug 01 '12 at 07:44
  • How are you saving? Are you doing everything inside a transaction? – Diego Mijelshon Aug 01 '12 at 10:14
  • I am using s#arp architecture repository. See PPS. – cs0815 Aug 01 '12 at 10:16
  • Create a simple unit test that saves new Node with a child Node inside a manually created session and transaction, so you can test the mapping and determine if it works or not independently from the rest of the app. – Diego Mijelshon Aug 01 '12 at 10:25