R – NHibernate maps to base instead of subclass

nhibernatenhibernate-mapping

In my business model I have Entity class (IPoint interface) that has a list of child elements of the same type. The link in DB is made via many-to-many table. The Entity has also discriminator for subclassing (IPoint implementations).

At first I made simple many-to-many mapping for this and all was working good. But then I've made (as best practices advices) one-to-many association instead of many-to-many in my mappings. To do so I created new class PointLink with composite-id that contains parent and child element. But NHibernate did not subclass these child elements (as it did when there was Many-To-Many association). He made his own Proxy objects (IPoint instances). It looks like he ignores subclass rule completely in reference. But for parent element subclass rule is used though.

The mapping of IPoint:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property"  auto-import="true" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" name="Elgsis.Core.IPoint, Elgsis.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Points">
<id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <column name="Id" />
  <generator class="identity" />
</id>
<discriminator type="String">
  <column name="Type" />
</discriminator>
<property name="Name" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <column name="Name" />
</property>
<bag cascade="all" inverse="true" name="Links">
  <key>
    <column name="ParentId" />
  </key>
  <one-to-many class="Elgsis.Core.PointLink, Elgsis.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bag>
<subclass name="Elgsis.Core.Meter, Elgsis.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="1" />
<subclass name="Elgsis.Core.Controller, Elgsis.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="2" />
</class>
</hibernate-mapping>

And the mapping of linking entity PointLink

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" name="Elgsis.Core.PointLink, Elgsis.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Points_Points">
<composite-id mapped="false" unsaved-value="undefined">
  <key-many-to-one name="Parent" class="Elgsis.Core.IPoint, Elgsis.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    <column name="ParentId" />
  </key-many-to-one>
  <key-many-to-one name="Child" class="Elgsis.Core.IPoint, Elgsis.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    <column name="ChildId" />
  </key-many-to-one>
</composite-id>
</class>
</hibernate-mapping>

Maybe I should use Class instead of Interface as base type, or it shouldn't be a big difference?

I am using latest NHibernate 2.1.0.4000 with FluentNHibernate 1.0.0.0

Thank you!

Best Answer

The problem was that lazy loading was turned on. Just turned it off for the referenced type and it is loading correctly now.

Good post about this behavior.

Related Topic