Is an EntityManager @Inject[ed] as follows in muliple classes threadsafe?
@PersistenceContext(unitName="blah") private EntityManager em;
Although EntityManager implementations itself are not thread safe the Java EE container injects a proxy which delegates all methods invocations to a transaction bound EntityManager. Therefore each transaction works with it's own EntityManager instance. This is true for at least transaction-scoped persistence context (which is default).
If container would inject a new instance of EntityManager in each bean the below wouldn't work:
doSomething->doSomethingAgainInTheSameTransaction call happens in a single transaction and therefore the beans must share the same EntityManager. Actually they share the same proxy EntityManager which delegates calls to the same persistence context.
So you are legal use EntityManager in singleton beans like below:
Another proof is that there is no any mention of thread safety in EntityManager javadoc. So while you stay inside Java EE container you shouldn't care about concurrency access to EntityManager.
To my great surprise (after years of using jpa in spring)
So why does it work in Spring? Because it wraps target
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
I feel I need to go deeper into this because my first answer was not absolutely true.
I will refer to JSR-220. In section 5.2 Obtaining an EntityManager you may find:
Well that's it. You may stop reading here and never use EntityManager in singleton beans unless properly synchronized.
But I believe there is a confusion in the spec. There are actually two different EntityManager implementations. The first is one is provider implementation (saying Hibernate) which is not obliged to be threadsafe.
On the other hand there is a container implementation of EntityManager. Which is also not supposed to be threadsafe according to the above. But container's implementation acts as a proxy and delegates all calls to the real provider's EntityManager.
So further in the spec in 5.9 Runtime Contracts between the Container and Persistence Provider:
This means in turn that there will be a different EntityManager instance for each transaction started. The code that creates an EntityManager is safe according to 5.3:
But what if there is an EntityManager associated with JTA transaction? The code that binds an EntityManager associated with current JTA transaction may be not threadsafe according to the spec.
But I can't really think of an application server implementation that works correctly with EntityManager injected into stateless beans and not correctly within singletons.
So my conclusions are: