Search code examples
c#fluent-nhibernate

How to correctly map & update a self referencing entity with fluent-nhibernate


I'm trying to create an entity which currently owns a List of the same entity, this link exists in another table.

This is then exposed as an API. I'm able to fetch data, but everytime I try to update the collection, it results in an error : a collection with cascade= all-delete-orphan was no longer referenced by the owning entity instance

public class MyEntity
{
   public virtual int Id { get; set; }
   public virtual ISet<MyEntity> LinkedEntities { get; set; }
}

I'm using fluent nhibernate automapping, and so, overriding the default mapping.

var fluentConfigurationCampaign = Fluently.Configure()
.CurrentSessionContext("mySession")
.Database(
          MySQLConfiguration.Standard.ConnectionString(MyConnectionString)
        )
        .Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<MyEntity>(cfg)
.Conventions.Setup(c => c.Add<CustomForeignKeyConvention>())
.Override<MyEntity>(map => map.HasManyToMany(i => i.LinkedEntities)
.ParentKeyColumn("EntitySelf")
.ChildKeyColumn("EntityOther")
.Table("Linked").Cascade.AllDeleteOrphan())

The linked table, as suggested by the mapping contains only 3 properties.

A self generated ID

A foreignKey EntitySelf linking to the Entity table

A foreignKey EntityOther linking to the Entity table.

When updating an entity (through a controller), I'm getting an EntityContract which is mapped through automapper to an Entity.

I then do :

_session.Merge(myEntityFromController);
var oldEntity = _session.Get<T>(myEntityFromController.Id);
_session.Update(oldEntity);
_session.Flush();

Which is working fine for all my other entities. But, trying to change the List of LinkedEntities (either by removing some, or adding, or even not touching it), I got the error : a collection with cascade= all-delete-orphan was no longer referenced by the owning entity instance

Any help would be appreciated as I'm stuck on this issue ! Thanks.


Solution

  • It seems my issue was related to the .Cascade.AllDeleteOrphan() part of the mapping. I thought it would reference to my Linked table, but instead, it seems it was trying to act on the MyEntity linked, hence producing my error.

    Removing it made everything works with no other tweak needed.