title: JPA EntityManger preforming a database insert on merge?
body: <p>I am using JPA with Hibernate underneath, and I am having trouble getting merge to work, 
  but before I describe the problems I am encountering with JPA, let me lay out what I am trying to accomplish, just in case my problems stems from my approach.</p>
  
  <p>I have data from on system that I need to place into another system. To do this I am reading the data then constructing new ORM objects based on that data, I then want to persist the ORM objects into the database. Now when the database is empty, the program works without issue, with a simple em.persist(object) call. However I want to be able to run this process when the database has data in it, adding new data and updating old data as necessary, this is where I am having issues.</p>
  
  <p>I do a simple check to see if the item already exists in the database, if nothing is found, I persist, if the record exists, I attempt a merge. Which fails with a duplicate record error;</p>
  
  <pre><code>ERROR JDBCExceptionReporter - Violation of UNIQUE KEY constraint 'UK-SubStuff-StuffId-SubStuffNumber'. Cannot insert duplicate key in object 'SubStuff'.
  </code></pre>
  
  <p>It strikes me as strange that the em.merge() call is attempting a insert instead of a update (I confirmed this through SQL logging).</p>
  
  <pre><code>Hibernate: insert into SubStuff (SubStuffNumber, StuffId, Name, TypeId) values (?, ?, ?, ?)
  </code></pre>
  
  <p>I should note that I am using objects that cascade into sub-objects. The failure is occurring on a sub-object, which makes sense to me as I would expect it to try and merge the sub-objects first.</p>
  
  <p>Below is my code, please excuse the rough state, I've tried to document a few workaround approaches here.</p>
  
  <pre><code>private void storeData(Collection&lt;Stuff&gt; Stuffs) {
  
      for (Stuff stuff : Stuffs) {
          //I think this first block can be safely ignored, as I am having no issues with it
          //  Left it in just in case someone more experianced then I sees the root of the issue here.
          Collection&lt;SubStuff&gt; subStuffs = stuff.getSubStuffCollection();
          for (SubStuff s : subStuffs) {
              //Persist SubStuff Type, which DOES NOT cascade,
              //  due to it not having an internal SubStuff collection
              Query q = em.createNamedQuery("SubStuffType.findByType");
              q.setParameter("type", f.getTypeId().getType());
              try {
                  SubStuffType sst = (SubStuffType) q.getSingleResult();
                  s.setTypeId(sst);
              } catch (NoResultException ex) {
                  if (logger.isDebugEnabled()) logger.debug("SubStuff Type not found, persisting");
                  em.persist(s.getTypeId());
              }
          }
  
          if (em.find(Stuff.class, stuff.getId()) == null) {
              //Persist on Stuffs will cascade to SubStuffs
              em.persist(stuff);
          } else {
              //  Failing to merge SubStuff, tries to insert duplicate
              //  Merge SubStuff first
              // The block below is my attempt to merge the SubStuff Collection before merging Stuff,
              //  it creates the same isuse as a straight merge of Stuff.
              Collection&lt;SubStuff&gt; mergedSubStuffs = new ArrayList&lt;SubStuff&gt;(SubStuffs.size());
              for (SubStuff s : SubStuffs) {
                  Query q = em.createNamedQuery("SubStuff.findBySubStuffNumberStuffId");
                  q.setParameter("SubStuffNumber", s.getSubStuffNumber());
                  q.setParameter("StuffId", stuff.getId());
                  try {
                      SubStuff subStuff = (SubStuff) q.getSingleResult();
          // -----&gt; Merge fails, with an duplicate insert error
                      SubStuff mergedSubStuff = em.merge(s);
                      mergedSubStuffs.add(mergedSubStuff);
                  } catch (NoResultException ex) {
                      throw ex;
                  }
              }
              stuff.setSubStuffCollection(mergedSubStuffs);
  
          // -----&gt; This will fails with same error as above, if I remove the attempt
              //  to merge the sub objects
              em.merge(stuff);
          }
      }
  }
  </code></pre>
  
  <p>If anyone with JPA experience can help me out I would really appreciate it. The differances between Hibernate's saveOrUpdate() and JPA's merge() are obviously tripping me up, but despite reading several articles on EnityManger's merge, I still can't wrap my head around what is going on here. </p>
  
  <p>Thanks for your time.</p>