Java CDI @PersistenceContext and thread safety

auser picture auser · Jun 16, 2012 · Viewed 10.3k times · Source

Is an EntityManager @Inject[ed] as follows in muliple classes threadsafe?

@PersistenceContext(unitName="blah")
private EntityManager em;

This question and this one seem to be Spring specific. I am using Jave EE CDI services

Answer

Tomasz Nurkiewicz picture Tomasz Nurkiewicz · Jun 16, 2012

To my great surprise (after years of using in ) 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 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 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 EntityManagerto 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.

See also