一尘不染

EntityManager在多线程应用程序中?

hibernate

EntityManager在多线程应用程序中如何使用Hibernate(例如,每个客户端连接在服务器上启动它自己的线程)。

EntityManager应该仅由EntityManagerFactory创建一次,例如:

private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("unit");
private static EntityManager em = emf.createEntityManager();
    public static EntityManager get() {
        return em;
    }

还是我必须为每个线程以及关闭EM的每个事务重新创建实体?

我的CRUD方法如下所示:

public void save(T entity) {
    em.getTransaction().begin();
    em.persist(entity);
    em.getTransaction().commit();
    em.close();
}

public void delete(T entity) {
    em.getTransaction().begin();
    em.remove(entity);
    em.getTransaction().commit();
    em.close();
}

我要不要emf.createEntityManager()每次都跑.begin()?还是因为每个人都使用自己的缓存创建自己的EntityManager实例而使我陷入麻烦了?


阅读 952

收藏
2020-06-20

共1个答案

一尘不染

5.1。
实体管理器和交易范围

EntityManager是一种廉价的,非线程安全的对象,应针对单个业务流程,单个工作单元使用一次,然后丢弃。

这完全可以回答您的问题。不要通过线程共享EM。只要一个事务处理是 工作单元的 一部分,就可以对多个事务使用一个EM 。

此外,关闭后无法使用EntityManger

调用close方法后,EntityManager实例上的所有方法以及从该实例获取的任何Query,TypedQuery和StoredProcedureQuery对象都将引发IllegalStateException。

考虑这样的事情:

public class Controller {

    private EntityManagerFactory emf;

    public void doSomeUnitOfWork(int id) {
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();

        CrudDao dao = new CrudDao(em);

        Entity entity = dao.get(id);
        entity.setName("James");
        dao.save(entity);

        em.getTransaction.commit();
        em.close();
    }

}
2020-06-20