多线程应用程序中的EntityManager?

时间:2014-01-08 13:43:32

标签: java database hibernate entitymanager

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

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实例?

1 个答案:

答案 0 :(得分:2)

<强> 5.1. Entity manager and transaction scopes

  

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

这完全回答了你的问题。不要在线程上共享EM。只要这些事务是工作单元的一部分,就可以将一个EM用于多个事务。

此外,在您closed之后,您无法使用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();
    }

}