Java – is entitymanager really thread safe?
I'm talking about the basic usage here:
@Stateless public class BookServiceBean implements BookService { @PersistenceContext EntityManager em; public void create(Book book) { this.em.persist(book);} }
When Google searches the above questions, stackoverflow says yes, but no – the accepted answer is yes, but the subsequent answer is no; Spring. IO said both yes and no, while Adam bien, who seems to be an expert in Java EE, gave unqualified yes
My experience with a simple scheduled bean shows that the answer is no:
@Stateless public class TimerTick implements TimerTickAbs,Runnable { @PersistenceContext private EntityManager entityManager; @Override public void run() { Query q = entityManager.createQuery("SELECT blah..."); } @Override public Runnable runner() { return this; } }
Abstract interface:
@Local public interface TimerTickAbs { public Runnable runner(); }
Start at:
@Resource Managedscheduledexecutorservice managedExecutorService; @EJB TimerTick myRunner; public void startup() { managedExecutorService.scheduleAtFixedRate(myRunner.runner(),3,40,TimeUnit.SECONDS); }
If I print thread currentThread(). Getid(), even if I am still on the same thread between calls, I get:
I know I can do code like the entitymanagerfactory EMF private to @ persistenceunit; And manage the entitymanager myself, but I want to use all the automatic transaction content given to me by @ persistencecontext
Solution
No, entitymanager is not thread safe Adam bien is also right You just don't see it right The question he answered was not that if the entitymanager is thread safe, he explained that using container managed entitymanger in stateless session beans is safe, and that's it Then he explained the reasoning and wording of the specification that allowed the container to exert its magic – "each instance can only see the serialized sequence of method calls" This allows the container to inject each method call with a different entitymanager context, similar to how each call binds to their own transactions and isolated resources
Injection is actually just an entitymanager agent, which allows the container to control the life cycle of the following JPA entitymanagers and bind it to threads and transactions
Therefore, the entitymanager is not thread safe, but the container injected into the entitymanager agent must be used safely in a stateless session bean