如何在多线程应用程序中使用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实例?
答案 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();
}
}