我在我的应用程序中以同样的方式使用了本教程:http://www.benmccann.com/hibernate-with-jpa-annotations-and-guice/ http://www.benmccann.com/hibernate-with-jpa-annotations-and-guice/
我的应用程序是 JAX-RS Web 服务,它将接收许多并发请求并对数据库进行更新。
GenericDAOImpl.java 实现:
public class GenericDAOImpl<T> implements GenericDAO<T> {
@Inject
protected EntityManager entityManager;
private Class<T> type;
public GenericDAOImpl(){}
public GenericDAOImpl(Class<T> type) {
this.type = type;
}
@Override
public void save(T entity) {
entityManager.getTransaction().begin();
entityManager.persist(entity);
entityManager.getTransaction().commit();
}
}
如果 2 个并发线程尝试保存实体,我得到
java.lang.IllegalStateException: Transaction already active
如果我评论交易,保存效果很好。
我尝试过使用
@Inject
protected Provider<EntityManager> entityManagerProvider;
or
@Inject
protected EntityManagerFactory entityManagerProvider;
对于每个请求:
EntityManager entityManager = entityManagerProvider.get()
但后来我得到:
org.hibernate.PersistentObjectException: detached entity passed to persist
实现 Guice + Hibernate EntityManager 注入/线程安全通用 DAO 类的正确方法是什么?
UPDATE
安德鲁·雷纳评论http://www.benmccann.com/hibernate-with-jpa-annotations-and-guice/ http://www.benmccann.com/hibernate-with-jpa-annotations-and-guice/
“这个逻辑还没有真正准备好投入生产——至少在网络应用程序中使用时是这样。
Hibernate 连接池非常基本,尚未准备好用于生产 - 建议使用数据源池,例如 c3p0。
EntityManager 不应该被重用——它应该根据事务/请求创建。很有可能污染后续请求。
如果出现问题,也不会发生事务回滚。
这是一种有趣的方法,但对于 Web 应用程序来说,使用 Guides 自己的 Persist 扩展模块来管理 EntityManager 实例和事务的生命周期会更安全。”