Search code examples
c#nhibernatenhibernate-mapping

Nhibernate inheritance mapping mixing Type-Per-Hierarchy with Type-Per-Class?


I'm trying to map this classes:

public interface IBusinessObject
{
    Guid Id { get; set; }
}
public class Product
{
    public virtual Guid Id { get; set; }
    public virtual int ProductTypeId { get; set; }
}
public class ProductWeSell : Product, IBusinessObject
{
}
public class ProductWeDontSell : Product
{
}

To database with 2 tables:

[BusinessObject] COLUMNS ([Id])
[Product] COLUMNS ([Id], [ProdyctTypeId])

I want to have Type-Per-Class for BusinessObject, and Type-Per-Hierarchy with Product. This should result in this behavior:

  • Add Product : INSERT INTO Product {Guid), null}
  • Add ProductWeDontSell : INSERT INTO Product {Guid, 2}
  • Add ProductWeSell: INSERT INTO BusinessObject {Guid}; INSERT INTO Product {SameGuid, 1}

Logically hbm mappings should be:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" name="IBusinessObject" table="BusinessObject">
    <joined-subclass name="ProductWeSell" table="Product"/>
  </class>
</hibernate-mapping>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" discriminator-value="null" name="Product" table="Product">
    <discriminator type="String">
      <column name="ProductTypeId" not-null="false" />
    </discriminator>
    <subclass name="ProductWeDontSell" discriminator-value="2" />
    <subclass name="ProductWeSell" discriminator-value="1" />
  </class>
</hibernate-mapping>

But I get {"Duplicate class/entity mapping ProductWeSell"} error.


Solution

  • I came to interesting conclusion. I decided to change my architecture and use separate classes for data access layer, and domain-UI layer, I just convert my objects when they cross the layer. Any way it is a good practice to have decoupled data-access and UI. So my data-access model now is pretty plain without any inheritance, inheritance appear only at domain-UI level.