I have a complex NHibernate structure to store our 3 level product hierarchy. When I try and save at level 3 (ProductDetail2), I get the following error:
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [Domain.Models.ProductDetail2#193150]
If I skip the level 3 save logic, it all goes through fine.
Our class inheritance is shown below. ProductDetail1 and ProductDetail2 are identical, apart from having a different ProductType (for historical reasons)
public abstract class Product {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual int ProductTypeId { get; set; }
...(other core product data)...
}
public class ProductDetail1 : Product {
public string ShortDescription { get; set; }
public override int ProductTypeId {
get { return (int)ProductTypeEnum.ProductOne; }
}
}
public class ProductDetail2 : ProductDetail1 {
public override int ProductTypeId {
get { return (int)ProductTypeEnum.ProductTwo; }
}
}
We are having to use two different types of subclass mappings, as per the definitions in Fluent Mapping
- Product and ProductDetail1 save to different tables - Table-per-subclass Mapping
- ProductDetail1 and ProductDetail2 save to the same table - Table-per-hierarchy Mapping (This is because the only thing that distinguishes them is the ProductTypeId)
Our Fluent mappings are as follows
public class ProductMap : ClassMap<Product> {
public ProductMap() {
Table("Product");
Id(x => x.Id).GeneratedBy.Identity();
Map(x => x.Name);
DiscriminateSubClassesOnColumn("ProductTypeId", 0);
}
}
public class ProductDetail1Map : SubclassMap<ProductDetail1> {
public ProductDetail1Map() {
Table("ProductDetail");
DiscriminatorValue((int)ProductTypeEnum.ProductOne);
Join(
"ProductOne",
y => {
y.KeyColumn("Id");
y.Map(x => x.ShortDescription);
});
}
}
public class ProductDetail2Map : SubclassMap<ProductDetail2> {
public ProductDetail2Map() {
DiscriminatorValue((int)ProductTypeEnum.ProductTwo);
}
}
Is this possible? If so, what am I doing wrong?
P.S. I also found this similar post, but it differs from our case in that it defines (and saves) Discriminator column at level 1, whereas we define it at level 0.