我正在开发一个应用程序,并且已经开始CDI与JSF和一起使用JPA。Web容器为Tomcat。
CDI
JSF
JPA
Tomcat
我对豆子的EntityManager生命周期感到非常困惑CDI,因此我需要一个很好的建议来清除一些想法。通常,我已阅读的内容EntityManager应主要在Java EE容器中使用,并使用PersistenceContext注释将其注入。因此,然后容器要注意其使用寿命。但是,如果您不使用Java EE容器(如Tomcat),那么我需要管理自己EntityManager的生活。
EntityManager
Java EE
PersistenceContext
现在,使用哪种方法是我最好的选择Tomcat, CDI, JSF and JPA?我现在正在做的事情如下:
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(); } }
因此,基本上,我只是使用Plain CDI来完成此操作。但是,我不确定这是否是标准方法,更重要的是,我不知道在EntityManager结束豆寿命后如何关闭。总结:我最终遇到了许多未关闭的连接EntityManager,因此内存泄漏。
有人可以帮助我了解如何继续吗?
这与CDI无关。EntityManager的生命周期取决于其类型,可以是:
前两个仅在功能完善的应用程序服务器中可用。因此,如果您要坚持使用servlet容器,则可以选择第3个选项。
您将必须在应用程序中显式打开和关闭EM。这很简单:创建EntityManagerFactory的应用程序范围的实例,然后将其注入所有bean。当您需要EM时,只需创建它,即可使用它,然后立即关闭,而无需等待bean的上下文结束。因为在此配置中,打开的EntityManager将保留连接,而对于寿命长的bean,您将用尽连接。您可以在ObjectDB手册的“ 获取JPA数据库连接” 部分中找到简单而全面的解释。