当前位置: 首页 > 面试题库 >

如何在CDI环境中管理EntityManager生命周期(使用Tomcat)

包丁雨
2023-03-14
问题内容

我正在开发一个应用程序,并且已经开始CDIJSF和一起使用JPA。Web容器为Tomcat

我对豆子的EntityManager生命周期感到非常困惑CDI,因此我需要一个很好的建议来清除一些想法。通常,我已阅读的内容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();
    }
}

因此,基本上,我只是使用Plain
CDI来完成此操作。但是,我不确定这是否是标准方法,更重要的是,我不知道在EntityManager结束豆寿命后如何关闭。总结:我最终遇到了许多未关闭的连接EntityManager,因此内存泄漏。

有人可以帮助我了解如何继续吗?


问题答案:

这与CDI无关。EntityManager的生命周期取决于其类型,可以是:

  1. 容器管理的交易,
  2. 容器管理扩展
  3. 应用程序管理。

前两个仅在功能完善的应用程序服务器中可用。因此,如果您要坚持使用servlet容器,则可以选择第3个选项。

您将必须在应用程序中显式打开和关闭EM。这很简单:创建EntityManagerFactory的应用程序范围的实例,然后将其注入所有bean。当您需要EM时,只需创建它,即可使用它,然后立即关闭,而无需等待bean的上下文结束。因为在此配置中,打开的EntityManager将保留连接,而对于寿命长的bean,您将用尽连接。您可以在ObjectDB手册的“
获取JPA数据库连接”
部分中找到简单而全面的解释。



 类似资料:
  • 我使用CDI注释定义了一个RequestScoped bean,如下所示。我有几个页面使用同一个bean。当我从一页导航到另一页时。bean obj保持不变。即使我更改了会话(使用不同的用户登录)。bean对象没有改变。 根据RequestScope定义,bean实例应该为每个新请求重新创建。我错过了什么? 我正在使用JSF/Primefaces。从create输入的值。导航到详细信息后可以看到x

  • 我试图使用django创建一个项目,并填充数据库,我的问题是,当我尝试创建一个新对象时,我得到了这个错误:重复键值违反了唯一约束,因为数据库已经填充,我可以做什么来更改它,使Postgres管理它或Djang0获得正确的序列?提前感谢

  • 我正在阅读关于Flux的文章,但是Todo应用程序的例子太简单了,我无法理解其中的一些关键点。 想象一下,像Facebook这样的单页应用程序拥有用户配置文件页面。在每个用户配置文件页,我们想显示一些用户信息和他们的最后一个帖子,无限滚动。我们可以从一个用户配置文件导航到另一个用户配置文件。 在Flux架构中,这将如何对应于存储和调度器? 我们是为每个用户使用一个,还是使用某种全局存储?那么dis

  • 问题内容: 我正在阅读有关Flux的信息,但示例Todo应用程序对于我来说太简单了,无法理解一些关键点。 想象一下像Facebook这样的具有 用户个人资料页 的单页应用程序。在每个用户个人资料页面上,我们要无限滚动地显示一些用户信息及其最新帖子。我们可以从一个用户个人资料导航到另一个。 在Flux体系结构中,这将与商店和调度员相对应吗? 我们会为每个用户使用一个,还是会有某种全球商店?调度程序呢

  • 该节将带领大家了解Kubernetes中的基本概念,尤其是作为Kubernetes中调度的最基本单位Pod。 本节中包括以下内容: 了解Pod的构成 Pod的生命周期 Pod中容器的启动顺序模板定义 Kubernetes中的基本组件kube-controller-manager就是用来控制Pod的状态和生命周期的,在了解各种controller之前我们有必要先了解下Pod本身和其生命周期。

  • 视图和bean一直在工作,直到我试图修复非标准名称,现在我已经打破了两者之间的连接。奇怪的是,“返回”按钮有正确的链接,但内容就是不显示,也不记录。为什么不执行Detail.get注释()? 我一直在浏览焊接文档,并试图更好地理解@Inject。似乎有一个我也不明白的生命周期问题。如果它不是生命周期,那么我甚至不能推测为什么Detail.get注释()从未在glassfish日志中显示: 值200