To my great surprise (after years of using jpa in spring) EntityManager
is not thread safe. This is actually understandable if you think about it deeper: EntityManager
is just a wrapper around native JPA implementation, e.g. session in Hibernate, which in turns is a wrapper around jdbc connection. That being said EntityManager
can't be thread safe as it represents one database connection/transaction.
So why does it work in Spring? Because it wraps target EntityManager
in a proxy, in principle using ThreadLocal
to keep local reference per each thread. This is required as Spring applications are built on top of singletons while EJB uses object pool.
And how can you deal with that in your case? I don't know cdi but in EJB each stateless and stateful session bean is pooled, which means you cannot really call method of the same EJB from multiple threads in the same time. Thus EntityManager
is never used concurrently. That being said, injecting EntityManager
is safe, at least into stateless and stateful session beans.
However injecting EntityManager
to servlets and singleton beans is not safe as possibly several threads can access them at the same time, messing up with the same JDBC connection.