0

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.

Community
  • 1
  • 1
maurocam
  • 411
  • 6
  • 15

1 Answers1

0

Thank goodness for Regression Tests!!!

The issue above was encountered by test that was failing. Upon investigation of the failure we were able to identify inconsistent data, which was (rightly) causing the NHibernate error.

The Fluent mapping outlined above does work correctly NHibernate spec - Para 8.1.4

maurocam
  • 411
  • 6
  • 15