Mind thread-safety when injecting EntityManager (2)
Continuing from the post Mind thread-safety when injecting EntityManager, here is a second part: container-managed EntityManager vs application-managed EntityManager.
There are important differences between the injected EntityManager
, and the EntityManager
created from an injected EntityManagerFactory
. Basically, injected EntityManager
is container-managed, meaning all of its lifecycle is controlled by the container (web container or EJB container). Application code cannot close it, or otherwise interfere with its life.
In addition, for a container-managed EntityManager
, its associated PersistenceContext
is automatically propagated along with the underlying JTA, from servlet A to servlet B, from servlet to EJB, from EJB a to EJB B, and so on. As such, EntityManager
of the same configuration injected into various classes can share the same PersistenceContext
in a call stack.
On the other hand, EntityManager
created from EntityManagerFactory
is application-managed EntityManager
. Application code is responsible for managing its whole lifecycle. And there is no PersistenceContext
propagation for application-managed EntityManager
.
Are all EntityManager
's obtained from EntityManagerFactory
application-managed EntityManager
? Yes.
Is it possible to get a container-managed EntityManager
from EntityManagerFactory
? No.
You may have read about the method EntityManagerFactory.getEntityManager()
, which returns a container-managed EntityManager
. This method was considered and included in the early draft version of Java Persistence API, but was eventually removed from its final release.