2
votes

I receive the following exception intermittently:

A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: Domain.Foo.Bars

The majority of the results on Google for this exception indicate that the problem occurs when you dereference a collection, instead of calling Clear() on the existing collection then adding new entities. However, this is not my problem.

Here is all the relevant code:

public class Foo
{
     public int Id { get; set; }

     private Iesi.Collections.Generic.ISet<Bar> _bars = new HashedSet<Bar>();
     public virtual ICollection<Bar> Bars       
     {
         get { return _bars; }
     }
}

public class Bar
{
     public int Id { get; set; }
     public DateTime Expiry { get; set; }
}

public class FooDbMap : ClassMap<Foo>
{
    public FooDbMap
    {
        Id(x => x.Id);

        HasMany(x => x.Bars)
            .Access.CamelCaseField(Prefix.Underscore)
            .KeyColumn("FooId")
            .LazyLoad()
            .Where("Expiry > (select getdate())")
            .AsSet()
            .Cascade.AllDeleteOrphan();
    }
}

You will see with this code that it is impossible to dereference the Bars collection, i.e. by doing this:

foo.Bars = new List<Boo>();

What could be causing the error?

1

1 Answers

0
votes

you should never mess with collection references created by NHibernate. First of all, NH creates proxy objects for lazy loading - replace that proxy with a List<> and NH has no way to either lazy load the contents OR detect wether any children have been removed. Secondly, NH watches mapped collections for changes (new entities, deletes etc.). Just replacing a collection with a new one that NH does know nothing about is not a good idea. NH will still have a reference to the managed collection, especially if you have NH monitor this collection and cascade all changes to contained children.

I would simply clear the collection to remove all entities instead of replacing the entire collection.