openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pinaki Poddar <>
Subject Re: EntityManager handling
Date Mon, 22 Dec 2008 19:52:15 GMT

 The following analogy is somewhat correct
   EntityManagerFactory <=> ConnectionPool
   EntityManager <=> Connection

  There are, however, some salient points regarding the affinity of
EntityManager transaction  vs. database transaction. EntityManager
transaction, under default optimistic mode, does not necessarily grab the
database connection throughout the transaction. That is the optimism -- a
particular EntityManager em1 assumes that nobody else is modifying the
instance x while it is being managed/updated by em1. This assumption allows
em1 to treat the database connections from the pool as identical i.e. one
can be grabbed whenever necessary and freed as soon as possible. A
'connection-less' modus operandi gives rise to favorable scaling behavior
which makes it possible to open, say N, EntityManager simultaneously with a
connection pool of only, say M, JDBC connections where N >> M. 
If the optimistic assumption is violated, then such violation is detected
during commit. 

> Is EntityManager analogous to connection in that each request should
> acquire
> its own EM and then close it at the end of the request?

True. But closing EntityManager essentially will clear up its cache. For a
higher performance, consider *not* closing EntityManager and pooling them, 
provided your application semantics allows for reuse of cached persistence
instances from a different transaction. 

> It seems the EM can detect when 2 objects representing the same row in the
> database are
> attempting a concurrent update (load A and B instances of same row, change
> A and B, update A, cool, > update B, error). Is this handled within a
> single EM instance? 
Not exactly. Let us say database has a row in PERSON table with primary key
In application code (in JSE environment):
  EntityManager em1 = emf.createEntityManager();
  Person p1 = em1.find(Person.class, "X");
  EntityManager em2 = emf.createEntityManager();
  Person p2 = em2.find(Person.class, "X");
  Person p1Again = em1.find(Person.class, "X"); // this will return p1 from
em1's cache

  // then following assertions hold true
  assert p1 != p2;
  assert p1.equals(p2); // provided Person.equals() method is written as
state comparison
  assert p1 == p1Again;

Effectively, JVM now has two separate Java instances p1 and p2 in two
separate caches of em1 and em2.
If both em1 and em2 modify p1 and p2 respectively and attempts commit, then
the later commit will fail.

View this message in context:
Sent from the OpenJPA Users mailing list archive at

View raw message