I have a Product object which references an ordered list of Specification objects. When the Product gets updated, the associated list of Specifications are .Clear()'d and rebuilt (not new'd.)
The problem with Cascade.All() is that when the Product is updated, it creates 20 new Specification rows in the database, abandoning the 20 old ones. Cascase.AllDeleteOrphans() throws an error:
Additional information: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: Invax.Core.Models.Product.Specifications
Although this is what I want to happen.. It's true, the collection of Specifications are no longer referenced by the Product -- so delete these, right? Well, I have tried Inverse() to allow the Specification objects themselves handle the relationship but it didn't work either. Here is my current mappings which throw the aforementioned error.
Product Mapping:
public class ProductMap : ClassMap<Product>
{
public ProductMap ()
{
Id(x => x.Id);
Map(x => x.CatalogId).Not.Nullable();
Map(x => x.Name).Not.Nullable();
Map(x => x.UrlSlug).Not.Nullable();
Map(x => x.ShortDescription).Not.Nullable();
Map(x => x.Description).Not.Nullable();
Map(x => x.ImageFileName);
HasMany(x => x.Specifications).Cascade.AllDeleteOrphan().KeyColumn("ProductId");
References(x => x.Category).Column("Category");
}
}
Specification Mapping:
class SpecificationMap : ClassMap<Specification>
{
public SpecificationMap()
{
Id(x => x.Id);
Map(x => x.Name);
Map(x => x.Value);
References(x => x.Product).Column("ProductReferenceId").Cascade.All();
}
}
I am open to any solution to this problem, including a more robust database design or data organization. I have to stick with Lists because the Specifications are ordered in a specific way.
Apparently too late for you, but if another one has this problem.
You should set the Cascade to Cascade.AllDeleteOrphan()
because
Cascade.All()
does not delete unreferenced child objects.