title: Cannot Merge an entity with a Composite Id when that entity has been previously retrieved using Get
body: <p>The project I am working on requires data in our system to be synchronized with that of another (the other system is quite popular which is why synchronization is so important).  However, I am having a weird issue when I attempt to update an existing entity that has a composite id.</p>
  
  <p>The problem is that whenever the entity to be updated is retrieved (using <strong>Get</strong>) prior to calling <strong>Merge</strong>, it does not work (the changes are not persisted to the DB but no exception is thrown).  When I remove the call to <strong>Get</strong>, updating the entity works.  Knowledge on whether the entity exists is needed because if it is being created, part of the composite id needs to be generated.</p>
  
  <pre><code>bool exists = ScanForInstance(instance);
  using (var session = SessionFactoryFactory.GetSessionFactory&lt;T&gt;().OpenSession())
  {
      if (exists)
      {
          instance = (T)session.Merge(instance);
      }
      else
      {
          KeyGenerator.Assign&lt;T&gt;(instance);
          newId = session.Save(instance);
      }
  
      session.Flush();
  }
  </code></pre>
  
  <p>The <strong>Get</strong> call is made in the <strong>ScanForInstance</strong> method:</p>
  
  <pre><code>private bool ScanForInstance&lt;T&gt;(T instance)
      where T : class
  {
      var id = IdResolver.ResolveObject&lt;T&gt;(instance);
      using (var session = SessionFactoryFactory.GetSessionFactory&lt;T&gt;().OpenStatelessSession())
      {
          return session.Get&lt;T&gt;(id) != null;
      }
  }
  </code></pre>
  
  <p>The <strong>IdResolver</strong> is used for determining what should be used for the id (the value of a single key in a mapping, otherwise the object itself for entities with composite ids).</p>
  
  <p>Like I said, if I remove the call to <strong>Get</strong> it works fine.  It works fine for all other operations as well (create, read, and deletes).  All operations, including updating, works fine for entities with single keys.</p>
  
  <hr>
  
  <p>The DB is Pervasive and there are a certain number of restrictions:</p>
  
  <ul>
  <li>No, I cannot change any of the schema (I see that as a frequent response to problems with FNB).</li>
  <li>I do not want to just delete then insert as there are some columns we do not sync back to our system and I do not want to wipe these out</li>
  </ul>
  
  <hr>
  
  <p><strong>UPDATED:</strong> I've added a simple example that people can copy/paste to test this weird behavior (if it is in fact universal).  I'm hoping people will do this to at least confirm my problem.</p>
  
  <p><strong>Type to be mapped, Fluent mapping:</strong></p>
  
  <pre><code>public class ParentType
  {
      public virtual long AssignedId { get; set; }
  
      public virtual long? GeneratedId { get; set; }
  
      public virtual string SomeField { get; set; }
  
      public override bool Equals(object obj)
      {
          return Equals(obj as ParentType);
      }
  
      private bool Equals(ParentType other)
      {
          if (ReferenceEquals(this, other)) return true;
          if (ReferenceEquals(null, other)) return false;
  
          return AssignedId == other.AssignedId &amp;&amp;
              GeneratedId == other.GeneratedId;
      }
  
      public override int GetHashCode()
      {
          unchecked
          {
              int hash = GetType().GetHashCode();
              hash = (hash * 31) ^ AssignedId.GetHashCode();
              hash = (hash * 31) ^ GeneratedId.GetHashCode();
  
              return hash;
          }
      }
  }
  
  public class ParentMap : ClassMap&lt;ParentType&gt;
  {
      public ParentMap()
      {
          Table("STANDARDTASKITEM");
  
          CompositeId()
              .KeyProperty(x =&gt; x.AssignedId, "STANDARDTASK")
              .KeyProperty(x =&gt; x.GeneratedId, "STANDARDTASKITEM");
  
          Map(x =&gt; x.SomeField, "DESCRIPTION");
  
          Not.LazyLoad();
      }
  }
  </code></pre>
  
  <p>Don't mind the fact it is called 'ParentType.'  I don't actually have any other mappings with this and don't actually use the type as a parent type in this example.  It is called this because I'm about to open another question that does involve problems with composite ids and inheritance (<strong>DON'T USE COMPOSITE ID'S! :-D</strong>).</p>
  
  <p>For the actual testing, I just created a console project in VS with this as the <strong>Program.cs</strong>:</p>
  
  <pre><code>static void Main(string[] args)
  {
      var smFactory = Fluently.Configure()
          .Database(() =&gt; new OdbcPersistenceConfigurer()
              .Driver&lt;OdbcDriver&gt;()
              .Dialect&lt;GenericDialect&gt;()
              .Provider&lt;DriverConnectionProvider&gt;()
              .ConnectionString(BuildSMConnectionString())
              .ProxyFactoryFactory(typeof(NHibernate.ByteCode.Castle.ProxyFactoryFactory))
              .UseReflectionOptimizer()
              .UseOuterJoin())
              .Mappings
              (m =&gt; 
                  m.FluentMappings.Add&lt;ParentMap&gt;()
              );
  
      var sessionFactory = smFactory.BuildSessionFactory();
  
      var updatedInstance = new ParentType
      {
          AssignedId = 1,
          GeneratedId = 13,
          SomeField = "UPDATED"
      };
  
      bool exists;
  
      using (var session = sessionFactory.OpenStatelessSession())
      {
          exists = session.Get&lt;ParentType&gt;(updatedInstance) != null;
      }
  
      using (var session = sessionFactory.OpenSession())
      {
          if (exists)
          {
              session.Merge(updatedInstance);
  
              session.Flush();
          }
      }
  }
  
  private static string BuildSMConnectionString()
  {
      // Return your connection string here
  }
  
  class OdbcPersistenceConfigurer : PersistenceConfiguration&lt;OdbcPersistenceConfigurer, OdbcConnectionStringBuilder&gt;
  {
  
  }
  </code></pre>
  
  <p>I know that adding this sample is only slightly more helpful since anyone wanting to test this would either need to change the ParentType field to conform to a table that they already have in their own DB, or add a table to match what is mapped in ParentType.  I'm hoping someone will do this at least out of curiosity now that I've given a good head-start on testing.</p>