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?
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.
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.
No, an EntityManager is NOT thread safe.
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.
Two JPA-specific reasons come to mind:
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.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With