title: How to map one-to-one relation as part of composite key in Fluent NHibernate
body: <p>I have two tables defining a parent-child relationship at the database level. The parent table has a single column primary key, and the child table has a composite primary key where one column refers to the parent table:</p>
  
  <pre><code>application table       tasks table
  = task_id (CK) -------&gt; = taskid (PK) 
  = user_id (CK)
  = transaction_id (CK)
  </code></pre>
  
  <p>Just for reference, the <code>user_id</code> and <code>transaction_id</code> columns do not refer to other tables.</p>
  
  <p>I'm trying to set up a Fluent NHibernate mapping for both entities in C#:</p>
  
  <pre><code>public class Application
  {
      public virtual string UserId { get; set; }
      public virtual string TransactionId { get; set; }
      public virtual string TaskId { get; set; }
  
      public virtual Task Task { get; set; }
  }
  
  public class Task
  {
      public string Id { get; set; }
  }
  </code></pre>
  
  <p>One <code>Application</code> has one <code>Task</code>, but one <code>Task</code> has many <code>Application</code>s. It is this relationship I'm having fits with.</p>
  
  <pre><code>internal class ApplicationMap : ClassMap&lt;Application&gt;
  {
      public ApplicationMap() : base()
      {
          Schema(...);
          Table(...);
  
          CompositeId()
              .KeyProperty(app =&gt; app.UserId, "user_id")
              .KeyReference(app =&gt; app.Task, "task_id")
              .KeyProperty(app =&gt; app.TransactionId, "transaction_id");
  
          // No explicit mapping defined for "task_id"
          // Other columns mapped, but omitted for brevity
      }
  }
  
  internal class TaskMap : ClassMap&lt;Task&gt;
  {
      public TaskMap()
      {
          Schema(DbSchema.SchemaName);
          Table(DbSchema.TableName);
  
          Id(task =&gt; task.Id, "taskid");
  
          // Other columns mapped, but omitted for brevity
  
          // Relations
          HasMany(task =&gt; task.Applications);
      }
  }
  </code></pre>
  
  <p>Upon inserting a new <code>Application</code> into the database, I get this exception:</p>
  
  <blockquote>
    <p>NHibernate.QueryException: could not resolve property: TaskId of: Application.</p>
  </blockquote>
  
  <p>I tried adding an explicit mapping to <code>ApplicationMap</code> for the <code>TaskId</code> property, but I got the super helpful "Index was out of range. Must be non-negative and less than the size of the collection." exception from NHibernate:</p>
  
  <pre><code>internal class ApplicationMap : ClassMap&lt;Application&gt;
  {
      public ApplicationMap() : base()
      {
          Schema(...);
          Table(...);
  
          CompositeId()
              .KeyProperty(app =&gt; app.UserId, "user_id")
              .KeyReference(app =&gt; app.Task, "task_id")
              .KeyProperty(app =&gt; app.TransactionId, "transaction_id");
  
          Map(app =&gt; app.TaskId, "task_id");
  
          // Other columns mapped, but omitted for brevity
      }
  }
  </code></pre>
  
  <p>After reading <a href="https://stackoverflow.com/questions/5378741/fluent-nhibernate-compositeid-to-mapped-class">Fluent NHibernate compositeid to mapped class</a>, I'm not sure what else to try. The difference between that question and this one is that the foreign key column on the child table does need to be mapped in the entity (<code>Application.TaskId</code>).</p>
  
  <p>I've been searching the Fluent NHibernate docs for while, and anything referring to composite primary keys has been hard to come by, especially when relationships to other tables are involved.</p>
  
  <h2>Why both <code>TaskId</code> and <code>Task</code> are needed</h2>
  
  <p>I do need <code>Application.Task</code> once in a while, but not very often. However, the composite key on the application table is used as a composite foreign key reference for all the other tables related to the application table. The <code>TaskId</code> property is going to be access <em>a lot</em>, and I'd like to avoid a JOIN query on the application and tasks table just to get a value already in the application table.</p>
  
  <h2>The "Failing" Unit Test</h2>
  
  <p>I had written a unit test for this mapping and repository in NHibernate, and it was failing:</p>
  
  <pre><code>var app = new Application(user)
  {
      TaskId = "...",
      // More properties being set...
  };
  
  db.Web.Applications.Create(app);
  db.SaveChanges();
  
  var actual = db.Web.Applications.Find(app.UserId, app.TaskId, app.TransactionId);
  
  // Test was failing here
  Assert.IsNotNull(actual.Task, "No task found");
  </code></pre>
  
  <p>The <em>real</em> problem seems to be that the <code>Task</code> property of the newly inserted record is null, and is not being lazy loaded after retrieving from the same NHibernate session (which after some research is the intended behavior).</p>
  
  <p>I had gone through many iterations of mappings, and actually did have a problem with the mapping initially. I just "kept having problems" because I didn't understand how NHibernate behaves on inserting new records.</p>