As I wrote in post Why we need type-level injections in JavaEE, injecting EJB 3 stateful beans into servlet instance fields is not thread-safe. Along the same line, injecting EntityManager with @PersistenceContext into servlet instance variables is not thread-safe, either. EntityManager is just not designed to be thread-safe.
For example, the following code snippet of a servlet class is incorrect:
One way to fix this is to inject EntityManagerFactory instead. EntityManagerFactory is guaranteed to be thread-safe. For example:
Continuing 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.
For example, the following code snippet of a servlet class is incorrect:
One way to fix this is to inject EntityManagerFactory instead. EntityManagerFactory is guaranteed to be thread-safe. For example:
Continuing 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.
No comments :
Post a Comment