title: What does "pre-existing" mean in the context of a managed entity instance in a JPA 2.0 persistence context?
body: <p>I believe I may have a fundamental misunderstanding with the JPA notion of a persistence context and how it is used by the <a href="http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#merge%28T%29" rel="nofollow"><code>EntityManager#merge(Object)</code></a> method.</p>
  
  <h2>Background</h2>
  
  <h3>Motivation</h3>
  
  <p>I want to be able to rely on a certain behavior of the <code>merge()</code> operation that I suddenly realized may not be happening.  Specifically, I want to rely on its hazily implied <code>UPSERT</code> capabilities.  For the purposes of this question, I am not interested in cascading behavior or caching of any sort.  Additionally, in this question I am not interested in how one vendor may happen to do things or how another may happen to do things; I am interested in the language and the requirements.</p>
  
  <p>This question is long and restated several times on purpose; I've found not everyone wraps their head around it in the same way, so I wanted to present it in a number of different ways.  Please excuse the verbosity.</p>
  
  <h3>Specification Citations</h3>
  
  <p>The <a href="http://jcp.org/en/jsr/detail?id=317" rel="nofollow">JPA 2.0 specification</a> says in section 7.1:</p>
  
  <blockquote>
    <p>A persistence context is a <strong>set of managed entity instances in which for any persistent entity identity there is a unique entity instance</strong> [emphasis mine]. Within the persistence context, the entity instances and their lifecycle are managed by the entity manager.</p>
  </blockquote>
  
  <p>(So this paragraph says: consider a set of objects; let's name it the persistence context.  Its members will have their lifecycles managed by an <code>EntityManager</code> and will correspond to their matching persistent representations off in database land.  Their <code>@Id</code>s, in other words, will match corresponding primary keys in the database.)</p>
  
  <p>Note that this paragraph does <em>not</em> say how an object gets into the set (how an entity gets into the persistence context), only what conditions must be true once you <em>do</em> have an object in there.  Rules on how things get into the set are laid down elsewhere in the specification.</p>
  
  <p>Finally, for completeness, it seems to be semantically OK to speak of an empty persistence context&mdash;it is the persistence context that results after you do <code>EntityManager#clear()</code>.</p>
  
  <p>Then section 3.2.7.1 says:</p>
  
  <blockquote>
    <p>The semantics of the merge operation applied to an entity X are as follows:</p>
    
    <p>• If X is a detached entity, the state of X is copied onto a <strong>pre-existing managed entity instance X' of the same identity</strong> or a new managed copy X' of X is created.</p>
  </blockquote>
  
  <h2>Question</h2>
  
  <p><strong>What, exactly, does pre-existing mean, when we speak of pre-existing managed entity instances in a persistence context?</strong>  </p>
  
  <p>Or: In a roundabout fashion, I'm really asking about what <code>clear()</code> does: does it truly empty the persistence context, or does it empty it <strong>only of objects to which I might currently retain references</strong>?</p>
  
  <p>Or: Suppose my persistence context is empty (I've just called <code>EntityManager#clear()</code>).  Are there any "pre-existing managed entity instance[s]" in it at <em>all</em>, of <em>any</em> identity?  Are <em>all</em> database rows sort of intrinsically present in a persistence context&mdash;i.e. the <code>clear()</code> operation doesn't really mean that the persistence context is truly <em>empty</em>, only that you can't get anything out of it without adding something to it?</p>
  
  <p>Or: in its implementation of the <code>merge()</code> operation, is an <code>EntityManager</code> implementation <strong>obligated</strong> by this paragraph to&mdash;at <code>merge()</code> time&mdash;go attempt to just-in-time look up, instantiate and manage X' so that it is as though the persistence context were <em>not</em> empty at the time <code>merge()</code> was called, like this:</p>
  
  <pre><code>// Assuming a previously empty persistence context (em.clear()).
  // Pseudocode follows as though this were part of the
  // EntityManager merge() implementation.
  //
  // Here "pre-existing" means "not there to start with,
  // but located just in time and thus snuck into the
  // persistence context from disk as though it had been
  // there all along".  This would mean that things like
  // primary key violations and the like at flush() time would be 
  // effectively prohibited by spec.
  SomeEntity xPrime = this.find(SomeEntity.class, x.getID());
  if (xPrime == null) {
    xPrime = new SomeEntity();
    manage(xPrime);
  }
  assert isManaged(xPrime); // hypothetical method
  copyProperties(x, xPrime);
  return xPrime;
  </code></pre>
  
  <p>Is <code>X'</code> in this case said to be pre-existing, even though at the time <code>merge()</code> was called the persistence context was empty?</p>
  
  <p>Or can, instead, a conformant <code>EntityManager</code> simply do:</p>
  
  <pre><code>// Assuming a previously empty persistence context.
  // Pseudocode follows as though it were part of the
  // EntityManager merge() implementation.
  //
  // Here "pre-existing" means "already in the persistence context",
  // which given that we're assuming we started with an empty one,
  // means we just do a new instance here.  This scares me but I can't
  // see how the spec rules this out.
  SomeEntity xPrime = new SomeEntity();
  copyProperties(x, xPrime);
  manage(xPrime);
  assert isManaged(xPrime); // hypothetical method
  return xPrime;
  </code></pre>
  
  <p>The justification for this interpretation would be the part of the sentence that says "...or a new managed copy X' of X is created", making me think that the JPA vendor can decide whether it wants to bother to do a <code>find()</code> first.  Under this second interpretation, where no <code>find()</code> is implicitly attempted, at <code>flush()</code> time it seems like you might get a primary key violation&mdash;the JPA provider might attempt an <code>INSERT</code> where an <code>UPDATE</code> should actually happen.</p>
  
  <p>Here is the same question made more concrete:</p>
  
  <p>Suppose my persistence context is empty (I have, say, called <code>EntityManager#clear()</code>).</p>
  
  <p>Suppose I have a detached entity in my hand, <code>X</code>, with an <code>@Id</code>-annotated <code>long</code> field that contains the value <code>6L</code>.  <code>EntityManager#contains(x)</code> returns <code>false</code>.</p>
  
  <p>Suppose I have an <code>x</code> table in my database with a row in it whose primary key is <code>6</code>, and suppose further that my <code>X</code> entity is mapped to it.</p>
  
  <p>(To blow my punchline early: can we say that <code>X'</code> pre-exists as a managed entity instance at this point?  Does it implicitly "pre-exist" because it can be managed instantly, just-in-time, so it is as though it exists?  Recall that we've just called <code>em.clear()</code>.)</p>
  
  <p>Now suppose I call <code>EntityManager#merge(Object)</code> on that detached entity (<code>X</code>).</p>
  
  <p>According to the specification, "the state of X is copied onto a pre-existing managed entity instance X' of the same identity, or a new managed copy X' of X is created".</p>
  
  <p>Is there a "pre-existing managed entity instance X' of the same identity" (<code>6</code> in this case) in the persistence context?  Recall that we've just called <code>em.clear()</code>.</p>
  
  <p>One interpretation says: No, of course there is not; the persistence context is empty; we <code>clear()</code>ed it; there's nothing in it; so the <code>EntityManager</code> can just fall back on the second part of the sentence ("...or a new managed copy X' of X is created").</p>
  
  <p>Another says: Yes, there is.  The <code>EntityManager</code> is required by the specification in this case to grab my <code>X</code>'s identifier, use it to quickly attempt the equivalent of a <code>find()</code> operation, which, when executed would silently place <code>X'</code> into the persistence context as though it had always been there before effectively beginning the <em>actual semantics</em> of the <code>merge()</code> operation.</p>
  
  <p>Which interpretation is correct?  I hope the latter.  Thanks for reading.</p>