NHibernate Discrimator

Go To StackoverFlow.com

0

I have a table called DomainType that contains several name/value pairs along with a Domain column that identifies rows that belong together. I have two C# classes called PackageType and ComponentType that both house their data in this same table with their Domain values being "PackageType" and "ComponentType" respectively. I thought I could use the NHibernate discrimator concept in my hbm.xml files to define these but every time I query for PackageTypes in my app I get back all rows from the DomainType table.

At this point I'm not sure if my mapping logic/syntax is bad or if I'm just misunderstanding the concept for discriminators. These are not subclasses after all so maybe this isn't the right strategy (?).

Here's the mapping file for my PackageType table:

 <class name="PackageType" table="DomainType" 
    discriminator-value="PackageType" dynamic-update="true">

    <id name="Id" column="Id" type="Int32" unsaved-value="0">
       <generator class="identity" />
    </id>

    <discriminator column="Domain" type="AnsiString" not-null="true" />

    <property name="Description" column="Description" 
     type="AnsiString" length="100" not-null="true" />
 </class>

Here's the C# code that returns all rows from the DomainType table (even ones where Domain="ComponentType"):

IEnumerable<PackageType> rslt = GetSession().Query<PackageType>().ToList();
2012-04-04 21:14
by sisdog
Discriminators only work on sub classes (i believe - Rippo 2012-04-05 05:20


1

You need to define an abstract class DomainType that both PackageType and ComponentType inherit from, then create a single mapping document DomainType.hbm.xml which contains the mapping for both of your subclasses. This is referred to Table-per-class-hierarchy in the NHibernate reference documentation.

<hibernate-mapping namespace=" ... " assembly=" ... ">
  <class name="DomainType" abstract="true" table="DomainType">
    <id name="Id" column="Id" type="Int32" unsaved-value="0">
       <generator class="identity" />
    </id>
    <discriminator column="Domain" type="AnsiString" not-null="true" />
    <subclass name="PackageType" discriminator-value="PACKAGE">
      <property .../>
    </subclass>
    <subclass name="ComponentType" discriminator-value="COMPONENT">
      <property .../>
    </subclass>
  </class>
</hibernate-mapping>

Then you can create a query for PackageType or ComponentType.

2012-04-05 10:45
by MartinB
So @MartinB, this is the heart of my question: does NHibernate require me to artificially introduce this new parent class DomainType even if I don't want it in my model? If not, that's cool, I'll learn to live with it. But, it seems like it would be easy enough for the NHibernate engine to use the discriminator concept without requiring an artificial parent class. In this app I'll never use the DomainType class directly. It serve no purpose in my domain and now might potentially confuse my colleagues when studying my model - sisdog 2012-04-05 20:13
Ads