Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keeping JPA EntityManager open?

Tags:

java

orm

jpa

I am learning JPA and the general pattern in examples seems to be as follows:

EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
// ....
em.getTransaction().commit();
em.close();

Now I am wondering why do we continually create and close EntityManagers, as opposed to keeping it open and just starting new transactions? What are the benefits and costs of keeping it open vs closing it all the time?

like image 478
corydoras Avatar asked Aug 03 '10 02:08

corydoras


People also ask

Does EntityManager need to be closed?

If you don't close it your entities will be kept as attached, even after you're done using them. Your context will be kept alive even when you can no longer access your EM. The JPA Specification contains more details.

How does EntityManager work in JPA?

In JPA, the EntityManager interface is used to allow applications to manage and search for entities in the relational database. The EntityManager is an API that manages the lifecycle of entity instances. An EntityManager object manages a set of entities that are defined by a persistence unit.

Is the JPA EntityManager object thread-safe?

No, an EntityManager is NOT thread safe.

Is EntityManager part of Hibernate?

Hibernate provides implementation of JPA interfaces EntityManagerFactory and EntityManager . EntityManagerFactory provides instances of EntityManager for connecting to same database. All the instances are configured to use the same setting as defined by the default implementation.


2 Answers

Two JPA-specific reasons come to mind:

  1. EntityManager is not guaranteed to be threadsafe by the JPA spec. Therefore, portable JPA apps can only use an EM in at most one thread at a time. The idiom of creating a method-local EM and closing it before it goes out of scope encourages stack confinement of EM references.

  2. An EM using the "Extended" Persistence Context Lifetime maintains a single persistence context for its entire existence. This means entities stop automatically detaching on commit(). Instead they must be manually detached, or else the EM remains responsible for tracking them.

This question is really a JPA-specific version of the old "when to pool objects" question. That's a tough one, but the answer is probably "rarely".

This old developerWorks post by Java concurrency expert Brian Goetz expounds the point. The gist: pools make great sense for costly objects, like database connections. But for short-lived, small, and quick-initializing objects like EntityManager, pooling or some other form of long-term reference retention is a hard sell.

But, it's a general question, so there are bound to be exceptions. Maybe the application is simple or singlethreaded. Then these concerns about threadsafety become moot.

like image 73
Dan LaRocque Avatar answered Oct 21 '22 19:10

Dan LaRocque


Keeping an entity manager open prevents it from returning it's connection to the connection pool.

This can lead to several problems especially in web applications, e.g. when the pool runs full and max connection size is reached, no other user can obtain a database connection preventing database access for that user.

In this case it is better to have short-living entity managers, e.g. open entity manager at the begin of a request and close it at the end of a request (can be done with listeners/interceptors..). The entities then become detached and you have to re-attach them if you want to use them again (using entity manager's merge operation).

like image 22
Sylar Avatar answered Oct 21 '22 18:10

Sylar