C# – How to manage a multiple-level class hierarchy in nhibernate with table per class hierarchy strategy

c++, nhibernate, nhibernate-mapping

I am trying to implement my object hierarchy in one table with the "table per class hierarchy" strategy in NHibernate. I'm getting an error with my NHibernate mapping that can be easily reproduced with a simple example. The error is:

System.NotSupportedException: Attempting to parse a null value into an sql string (column:activity0_.Type).at NHibernate.SqlCommand.InFragment.ToFragmentString() in InFragment.cs: line 109at NHibernate.Persister.Entity.SingleTableEntityPersister.DiscriminatorFilterFragment(String alias) in SingleTableEntityPersister.cs: line 551

I can reproduce this with the following domain classes:

public interface IActivity{    Guid Id { get; set; }}public abstract class Activity : IActivity{    public DateTime StartTime { get; set; }    public Guid Id { get; set; }}public class Running : Activity{    public string Where { get; set; }}public class Talking : Activity{    public string ToWhom { get; set; }}

And the following XML mapping:

<?xml version="1.0" ?><hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"                   assembly="NHibernateTesting"                   namespace="NHibernateTesting" >  <class name="IActivity"         lazy="false"         table="Activity"         discriminator-value="0"         abstract="true">    <id name="Id">      <generator class="guid" />    </id>    <discriminator column="Type" type="Int16" />    <subclass name="Activity"              discriminator-value="1"              abstract="true"              lazy="false">      <property name="StartTime" />    </subclass>    <subclass name="Running"              discriminator-value="2"              lazy="false"              extends="Activity">      <property name="Where" />    </subclass>    <subclass name="Talking"              discriminator-value="3"              lazy="false"              extends="Activity">     <property name="ToWhom" />    </subclass>  </class></hibernate-mapping>

Does anyone have an idea of what I am doing wrong?

Best Solution

I'm not that familiar with c# and NHibernate but are you sure Activity should be set as abstract="true" in the mapping? It looks like the Activity class isn't abstract.

Shouldn't Running and Talking reside inside of Activity else the StartTime won't be saved. Right?

<subclass name="Activity"...  <subclass name="Running"  ...  </subclass>  <subclass name="Talking"  ...  </subclass>...</subclass>

Anyhow the errormessage suggest that NHibernate is trying to create some query with an in-statement. But there are no values for it. Basically it tries to bild something like

...WHERE foo IN (null)

If I parsed the code correctly. What are you trying to do when hit throws this error?

Did you already try to enable these in the hibernate-configuration to check what is going on?

<property name="show_sql">true</property><property name="hibernate.format_sql">true</property><property name="hibernate.use_sql_comments">true</property>