title: How to use NHibernate DiscriminateSubClassesOnColumn and References for the same column
body: <h1>The Setup</h1>
  
  <p>I am using <a href="http://www.fluentnhibernate.org" rel="noreferrer">FluentNHibernate</a> 1.4.0 for my NHibernate 3.3.3-SP1 mappings in a .NET4.0 library. I'm using the "table-per-inheritance" approach for my type hierarchy as follows:</p>
  
  <pre class="lang-sql prettyprint-override"><code>-- Different process types potentially use 
  -- different types of reference values
  CREATE TABLE ProcessTypes
  (Id INT PRIMARY KEY)
  
  -- Contains reference values for value comparisons
  CREATE TABLE ProcessReferenceValues
  (Id INT PRIMARY KEY IDENTITY(1,1),
   ProcessTypeId INT FOREIGN KEY REFERENCES ProcessTypes(Id),
   FloatReferencesValue FLOAT NULL,
   IntReferenceValue INT NULL)
  </code></pre>
  
  <pre class="lang-cs prettyprint-override"><code>// POCOs
  
  class ProcessReferenceValues
  {
      public virtual int Id { get; set; }
      public virtual ProcessTypes ProcessType { get; set; }
      public virtual float? FloatReferenceValue { get; set; }
      public virtual int? IntReferenceValue { get; set; }
  }
  
  class IntProcessReferenceValues : ProcessReferenceValues { }
  
  class FloatProcessReferenceValues : ProcessReferenceValues { }
  
  enum ProcessTypeName : int
  {
      IntProcess = 1,
      FloatProcess = 2
  }
  
  class ProcessTypes
  {
      public virtual int Id { get; set; }
      public virtual ProcessTypeName Name { get; set; }
  }
  
  // FluentNHibernate Mappings
  
  class ProcessReferenceValuesMap 
      : FluentNHibernate.Mapping.ClassMap&lt;ProcessReferenceValues&gt;
  {
      public ProcessReferenceValuesMap()
      {
          string processTypeId = "ProcessTypeId";
  
          this.Id(x =&gt; x.Id);
          this.Map(x =&gt; x.FloatReferenceValue).Nullable();
          this.Map(x =&gt; x.IntReferenceValue).Nullable();
  
          // Here is the tricky bit
          this.References(x =&gt; x.ProcessType, processTypeId);
          this.DiscriminateSubClassesOnColumn(processTypeId);
      }
  }
  
  class IntProcessReferenceValuesMap 
      : FluentNHibernate.Mapping.SubclassMap&lt;IntProcessReferenceValues&gt;
  {
      public IntProcessReferenceValuesMap()
      {
          this.DiscriminatorValue((int)ProcessTypeName.IntProcess);
      }
  }
  
  class FloatProcessReferenceValuesMap 
      : FluentNHibernate.Mapping.SubclassMap&lt;FloatProcessReferenceValues&gt;
  {
      public FloatProcessReferenceValuesMap()
      {
          this.DiscriminatorValue((int)ProcessTypeName.FloatProcess);
      }
  }
  
  class ProcessPeriodTypesMap : FluentNHibernate.Mapping.ClassMap&lt;ProcessPeriodTypes&gt;
  {
      public ProcessPeriodTypesMap()
      {
          this.ReadOnly();
          this.Id(x =&gt; x.Id, "id");
          this.Map(x =&gt; x.Name, "id").ReadOnly().CustomType&lt;PeriodTypeName&gt;();
      }
  }
  </code></pre>
  
  <h1>The Problem</h1>
  
  <p>While reading from the database works like a charm - the appropriate sub classes are selected correctly - saving a new process reference value gives me an exception:</p>
  
  <pre class="lang-cs prettyprint-override"><code>// Reading
  
  var processType =
     (from type in session.Query&lt;ProcessTypes&gt;()
      where type.Name == ProcessTypeName.IntProcess
      select type).FirstOrDefault(); // OK, finds the IntProcess
  
  var referenceValues =
     (from val in session.Query&lt;ProcessReferenceValues&gt;()
      select val).ToList(); // OK, finds the appropriate subclasses
  </code></pre>
  
  <pre class="lang-cs prettyprint-override"><code>// Inserting
  
  var processType = new ProcessTypes
  {
      Id = (int)ProcessTypeName.IntProcess
  };
  
  var referenceValue = new ProcessReferenceValues
  {
      FloatReferenceValue = 0.7f,
      IntReferenceValue = null,
      ProcessType = processType // Needs the appropriate ProcessType
  };
  session.Save(referenceValue); // &lt;- BOOM!
  </code></pre>
  
  <pre>
  Error dehydrating property value for ProcessReferenceValues.ProcessType
  
  Invalid Index 2 for OleDbParameterCollection with Count=2.
      bei System.Data.OleDb.OleDbParameterCollection.RangeCheck(Int32 index)
      bei System.Data.OleDb.OleDbParameterCollection.GetParameter(Int32 index)
      bei System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item(Int32 index)
      bei NHibernate.Type.Int32Type.Set(IDbCommand rs, Object value, Int32 index) in p:\nhibernate-core\src\NHibernate\Type\Int32Type.cs:Zeile 60.
      bei NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int32 index) in p:\nhibernate-core\src\NHibernate\Type\NullableType.cs:Zeile 182.
      bei NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session) in p:\nhibernate-core\src\NHibernate\Type\NullableType.cs:Zeile 122.
      bei NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session) in p:\nhibernate-core\src\NHibernate\Type\ManyToOneType.cs:Zeile 50.
      bei NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) in p:\nhibernate-core\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:Zeile 2410.
  </pre>
  
  <p>As always in hard times I summoned the gooragle and the problem seems to be that the <code>this.DiscriminateSubClassesOnColumn(processTypeId)</code> adds a conflict with the <code>this.References(x =&gt; x.ProcessType, processTypeId)</code> mapping. When I remove the former the insert is successful but I want the subclass mapping AND I also need to be able to set the <code>ProcessReferenceValues.ProcessType</code> when adding new instances of <code>ProcessReferenceValues</code> to distinguish the subclasses.</p>
  
  <h1>The Question</h1>
  
  <p>Is it possible to discriminate subclasses on a column and at the same time referencing that same column on the same type?</p>
  
  <p>Help very much appreciated, there's got to be a way to do this ...</p>
  
  <p><em>thx in advance!</em></p>