title: JPA EntityManager.merge() attemps to cascade the update to deleted entities
body: <p>I'm facing a problem with EntityManager.merge() where the merge is cascaded to other entities that have already been deleted from the database. Say I have the following entities:</p>
  
  <pre><code>@Entity
  public class Parent {
    @OneToMany(cascade = CascadeType.ALL, orphanremoval = true, mappedBy = "parent")
    private List&lt;Child&gt; children;
  
    public void clearChildren() { children.clear(); }
    public void createChildren(Template template) { ... }
  }
  
  @Entity
  public class Child {
    @ManyToOne
    @JoinColumn(name = "parentId")
    private Parent parent;
  }
  </code></pre>
  
  <p>The situation where the problem occurs is the following:</p>
  
  <ol>
  <li>The user creates a new Parent instance, and creates new Child instances based on a template of their choosing by calling the createChildren() method. The template defines the amount and properties of the created children.</li>
  <li>The user saves the parent, which cascades the persist to the children.</li>
  <li>The user notices that the used template was wrong. He changes the template and saves, which results in deletion of the old children and the creation of new ones.</li>
  </ol>
  
  <p>Commonly the deletion of the old children would be handled automatically by the orphanRemoval property, but the Child entity has a multi-column unique index, and some of the new children created based on the new template can have identical values in all columns of the index as some of the original children. When the changes are flushed to the database, JPA performs inserts and updates before deletions (<a href="http://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/event/internal/AbstractFlushingEventListener.html#performExecutions%28org.hibernate.event.spi.EventSource%29" rel="nofollow">or at least Hibernate does</a>), and a constraint violation occurs. Oracle's deferred constraints would solve this, but we also support MS SQL, which AFAIK doesn't support deferred constraints (correct me if I'm wrong).</p>
  
  <p>So in order to solve this, I manually delete the old children, flush the changes, create the new children, and save my changes. The artificial code snippet below shows the essential parts of what's happening now. Due to the way our framework works, <strong>the entities passed to this method are always in a detached state</strong> (which I'm afraid is a part of the problem).</p>
  
  <pre><code>public void createNewChildren(Parent parent, Template template) {
    for (Child child : parent.getChildren()) {
      // Have to run a find since the entities are detached
      entityManager.remove(entityManager.find(Child.class, child.getId()));
    }
    entityManager.flush();
    parent.clearChildren();
    parent.createChildren(template);
    entityManager.merge(parent); // EntityNotFoundException is thrown
  }
  </code></pre>
  
  <p>The last line throws an exception as the EntityManager attempts to load the old children and merge them as well, but fails since they're already deleted. The question is, <strong>why does it try to load them in the first place?</strong> And more importantly, <strong>how can I prevent it?</strong> The only thing that comes to my mind that could cause this is a stale cache issue. I can't refresh the parent as it can contain other unsaved changes and those would be lost (plus it's detached). I tried setting the parent reference explicitly to null for each child before deleting them, and I tried to evict the old children from the 2nd level cache after deleting them. Neither helped. We haven't modified the JPA cache settings in any way.</p>
  
  <p>We're using Hibernate 4.3.5.</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>We are in fact clearing the children from the parent as well, this was maybe a bit ambiguous originally so I updated the code snippets to make it clear.</p>