Java CDI @PersistenceContext and thread safety

后端 未结 3 1749
粉色の甜心
粉色の甜心 2020-12-13 07:12

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

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

3条回答
  •  眼角桃花
    2020-12-13 07:37

    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 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

    • Mind thread-safety when injecting EntityManager
    • The EntityManager is not thread-safe

提交回复
热议问题