JPA EntityManager Static or Instance?

In the past, I created JPA stuff that used an instance of javax.persistence.EntityManager for each instance of the DAO; this is the way most examples are set up.

 public class BaseDaoThatEveryDaoExtends { @PersistenceContext private EntityManager entityManager; } 

I just came across a code that uses static javax.peristence.EntityManger , introduced by the PersistenceContext annotation, the architect tells me that this is not a problem, and they never had a problem even in a clustered application with JTA and XA data source:

 public class BaseDaoThatEveryDaoExtends { @PersistenceContext private static EntityManager entityManager; } 

As far as I can tell, this is an anti-pattern, since the EntityManager contains some status information and makes it static, which makes this application as a whole wide. It also makes tests very difficult to test.

Are there other disadvantages for this, or is this the standard way to use EntityManager ?

+6
source share
3 answers

I think that the main risk is not in the EntityManager itself, but in the context of the application, which is tied to the entity manager when using it.

Suppose you have two different clients making a request to your server, both calling two different methods of your application, working on different threads, but both using the same entity manager.

As far as I know, the object manager will have one context bound to it, this context will be shared by both clients. Each time you load an instance into a context, it will be available for flows through the general object manager. What happens if they change each other's data? What happens if they use transaction isolation configuration? How can you be sure that client 1 is not modifying the data currently used by client 2?

What if one of the clients invalidates the context, what will the other do? How do you feel about concurrency in this way?

+4
source

EntityManager stores its data using threadlocal, so it might be nice to keep a static link to it, since all threads accessing it will be processed independently. In fact, I won’t be surprised if the EJB context is stored in the EntityManager in a static way using the singleton pattern.

Personally, I would never define it in a static way. This seems unnecessary, and in the worst case, there may be some unforeseen side effects.

One of the problems I see is the ability to inadvertently access entityManager from a static method:

 public class BaseDaoThatEveryDaoExtends { @PersistenceContext private static EntityManager entityManager; public static void doSomeStaticWork(){ ... entityManager.doSomething; //NPE possible! } } 

I could see that EntityManager is not being entered and in this case NPE appears.

In addition, some issues related to testing / bullying using the EntityManager may occur.

+1
source

EntityManagerFactory is guaranteed to be thread safe, so I think this is the β€œright” way: Use EMF in insecure places and keep EntityManger from threading issues.

0
source

Source: https://habr.com/ru/post/904417/


All Articles