【发布时间】:2013-12-08 14:15:20
【问题描述】:
我正在开发一个应用程序,我已经开始使用CDI 以及JSF 和JPA。 Web 容器是Tomcat。
我对 CDI bean 中的 EntityManager 生命周期感到非常困惑,我需要一个好的建议来清除我脑海中的一些东西。
一般来说,我读到的是EntityManager 应该主要用于Java EE 容器中,使用PersistenceContext 注释注入它。所以容器会关心它的生命。但是,如果你不使用Java EE 容器(如Tomcat),那么我需要管理我的EntityManager 的生活。
使用Tomcat, CDI, JSF and JPA,我现在最好的选择是什么?
我现在正在做的事情如下:
public class EntityManagerFactoryProducer {
public static final String TEST = "test";
@Produces
@ApplicationScoped
public EntityManagerFactory create() {
return Persistence.createEntityManagerFactory(TEST);
}
public void destroy(@Disposes
EntityManagerFactory factory) {
factory.close();
}
}
public class EntityManagerProducer {
@Inject
private transient Logger logger;
@Inject
private EntityManagerFactory emf;
@Produces
public EntityManager create() {
return emf.createEntityManager();
}
public void destroy(@Disposes
EntityManager em) {
em.close();
logger.debug(String.format("%s Entity manager was closed", em));
}
}
@Named
@ViewScoped
@Interceptors(LoggingInterceptor.class)
public class ProductBacking implements Serializable {
@Inject
private ProductDAO productDAO;
@ViewScoped
public class ProductDAOImpl implements ProductDAO, Serializable {
private static final long serialVersionUID = 4806788420578024259L;
private static final int MAX_RANDOMIZED_ELEMENTS = 3000;
@Inject
private transient Logger logger;
@Inject
private EntityManager entityManager;
@Override
public List<Product> getSuggestedProducts() {
logger.debug(String.format("%s Entity manager get products", entityManager));
return entityManager.createQuery("SELECT p FROM Product p ORDER BY random()", Product.class).setMaxResults(
MAX_RANDOMIZED_ELEMENTS).getResultList();
}
@Override
public void saveProduct(Product product) {
logger.debug(String.format("%s Entity manager save product", entityManager));
entityManager.getTransaction().begin();
entityManager.merge(product);
entityManager.getTransaction().commit();
}
@PreDestroy
void destroy() {
entityManager.close();
}
}
所以基本上我只是使用普通的CDI 来完成这个。
但是,我不确定这是否是标准的做法,更重要的是,我不知道在 bean 生命结束后如何关闭EntityManager。
作为总结:我最终有许多未关闭的连接(EntityManagers),所以内存泄漏。
有人可以帮助我了解我应该如何进行吗?
【问题讨论】:
-
你愿意尝试 Tomcat 以外的东西吗?
-
@JoshuaWilson 一般来说是的,但我有点被这个环境所困扰。你会推荐哪一个? TomEE,Glassfish?
-
如果您所做的只是 servlet 和 jsp,那么 Tomcat 就可以了。当您开始添加 JEE 的所有部分时,您正在构建自己的应用服务器。这样做会带来更大的风险和更高的维护。我会推荐JBoss/Wildfly,它是免费的,它旨在做你想做的事。
标签: java hibernate jakarta-ee jpa cdi