title: OpenJPA vs Hibernate: significant difference between EntityManager.merge
body: <p>So, I'm seeing major differences in behavior between OpenJPA (2.1.1) and Hibernate (3.3.1) with EntityManager.merge.  Consider the following class:</p>
  
  <pre><code>@Entity(name = "ChoiceHolder")
  @Table(name = "CHOICEHOLDER")
  @Inheritance(strategy = InheritanceType.JOINED)
  public class ChoiceHolder
      implements Equals, HashCode
  {
  
      protected int id;
      protected String choice3;
      protected String choice4;
  
      @Id
      @Column(name = "ID", scale = 0)
      public int getId() {
          return id;
      }
  
      public void setId(int value) {
          this.id = value;
      }
  
      @Basic
      @Column(name = "CHOICE3", length = 255)
      public String getChoice3() {
          return choice3;
      }
  
      public void setChoice3(String value) {
          this.choice3 = value;
      }
  
      @Basic
      @Column(name = "CHOICE4", length = 255)
      public String getChoice4() {
          return choice4;
      }
  }
  </code></pre>
  
  <p>And consider the following client code (this is just an SSCCE - in my actual use case, the two calls to merge with the same ID reflect received data from two separate client operations, where the id is intended to be the same between the two ops):</p>
  
  <pre><code>ChoiceHolder holder1a = new ChoiceHolder();
  holder1a.setId(1);
  holder1a.setChoice3("foo");
  ChoiceHolder holder1b = new ChoiceHolder();
  holder1b.setId(1);
  holder1b.setChoice4("bar");
  
  EntityManager em1 = factory.createEntityManager();
  em1.merge(holder1a);
  em1.close();
  EntityManager em2 = factory.createEntityManager();
  em2.merge(holder1b);
  em2.close();
  EntityManager em1Find = factory.createEntityManager();
  ChoiceHolder holder1result = em1Find.find(ChoiceHolder.class, 1);
  em1find.close();
  
  ChoiceHolder holder2a = new ChoiceHolder();
  holder2a.setId(2);
  holder2a.setChoice3("foo2");
  ChoiceHolder holder2b = new ChoiceHolder();
  holder2b.setId(2);
  holder2b.setChoice4("bar2");
  
  EntityManager em3 = factory.createEntityManager();
  em3.merge(holder2a);
  em3.merge(holder2b);
  em3.close();
  EntityManager em2Find = factory.createEntityManager();
  ChoiceHolder holder2result = em2Find.find(ChoiceHolder.class, 2);
  em2Find.close();
  </code></pre>
  
  <p>When I run the above code using Hibernate, <code>holder1result</code> has null for choice3, and "bar" for choice4.  Likewise, <code>holder2result</code> has null for choice3, and "bar2" for choice4.  However, when I run the same code using openJPA, I get something very different: <code>holder1result</code> has both choice3 and choice4 set, and the call to <code>em3.merge(holder2b)</code> blows up with a ReportingSQLException, because the INSERT it tries to do violates the primary key constraint on choiceholder's ID.  </p>
  
  <p>If it matters, here are the relevant bits from the properties file I'm using to configure Hibernate:</p>
  
  <pre><code>hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
  hibernate.connection.driver_class=org.postgresql.Driver
  hibernate.hbm2ddl.auto=create-drop
  hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider
  hibernate.jdbc.batch_size=0
  </code></pre>
  
  <p>And here's the corresponding bit from my persistence.xml that is being used to configure openJPA:</p>
  
  <pre><code>&lt;property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/&gt;
  &lt;property name="openjpa.jdbc.DBDictionary" value="postgres"/&gt;
  &lt;property name="openjpa.ConnectionDriverName" value="org.postgresql.Driver"/&gt;
  &lt;property name="openjpa.jdbc.MappingDefaults" value="DeferConstraints=true,ForeignKeyDeleteAction=restrict,JoinForeignKeyDeleteAction=restrict"/&gt;
  </code></pre>
  
  <p>In my particular case, what I want is the behavior I'm seeing with Hibernate; however, I'm required by my environment (inside Karaf) to use OpenJPA instead.  Are there flags I can set on OpenJPA to alter its behavior to match what I'm looking for?</p>
  
  <p>Is this a horrific abuse of JPA, and if so, is there some other technique/sequence of calls I should be using?</p>
  
  <p>Thanks in advance!</p>