Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 我们是否需要在select调用中关闭EntityManager资源 选择呼叫泄漏连接_Hibernate_Jpa - Fatal编程技术网

Hibernate 我们是否需要在select调用中关闭EntityManager资源 选择呼叫泄漏连接

Hibernate 我们是否需要在select调用中关闭EntityManager资源 选择呼叫泄漏连接,hibernate,jpa,Hibernate,Jpa,我们是否需要在select调用中关闭EntityManager资源,否则会泄漏连接。当然,始终要关闭EntityManager。如果您使用EMF创建自己的EntityManager实例,则需要关闭它们 如果您在一个受管理的容器(例如JBoss AS或任何其他EJB容器)中运行,那么您可以将EntityManger注入到您的bean中,然后您不必担心关闭它 从您显示的代码片段来看,您的应用程序似乎是一个独立的应用程序,而不是运行在某些Java EE容器(如JBoss AS或Spring)中的托管应

我们是否需要在select调用中关闭EntityManager资源,否则会泄漏连接。

当然,始终要关闭EntityManager。

如果您使用EMF创建自己的EntityManager实例,则需要关闭它们


如果您在一个受管理的容器(例如JBoss AS或任何其他EJB容器)中运行,那么您可以将EntityManger注入到您的bean中,然后您不必担心关闭它

从您显示的代码片段来看,您的应用程序似乎是一个独立的应用程序,而不是运行在某些Java EE容器(如JBoss AS或Spring)中的托管应用程序(为了便于讨论,可以将其视为Java EE容器)。 根据以下说明,您正在应用程序管理的实体管理器中运行。因此,您需要显式关闭实体管理器和工厂

我想澄清一下,您需要关闭交易边界处的EntityManager。如果您将查看hibernate会话的代码(EntityManagerImpl.close()实际委托给会话关闭)。您将注意到它关闭事务并清除持久性上下文。关闭EntityManagerFactory更多的是在应用程序级别,因此您可以重用它,并在销毁应用程序时关闭它

这么说,并关注连接泄漏,请注意,连接不是由hibernate直接管理的。Hibernate有一个插件体系结构,允许与连接池集成。Hibernate(我想从3.3版开始,还不确定)附带了一个默认的连接池机制,不推荐用于生产环境。如果您使用的是默认连接,则可能是导致连接泄漏的原因(请参阅下文)

与hibernate一起使用的最常见的连接池是C3P0(我不确定它是否是最好的)。
在非托管环境中,您需要验证连接池的配置(例如hibernate.c3p0.*相关的hibernates属性)

我有类似的连接泄漏。根本原因是select语句隐式启动事务。调用EntityManager.close()时,该事务仍处于活动状态,并且出于某种原因,该事务保持连接打开

更糟糕的是,我们的连接池从未回收处于这种状态的连接

我的解决方案是在关闭任何entityManager之前显式检查活动事务。我为此编写了一个小助手函数:

public static void rollbackAndClose(EntityManager mgr) {
    if (mgr != null) {
        EntityTransaction transaction = mgr.getTransaction();
        if (transaction.isActive()) {
            transaction.rollback();
        }
        mgr.close();
    }
}

(我习惯于在断开SQL客户端与Oracle或SQLServer的连接时自动回滚事务,因此EntityManager行为对我来说是违反直觉的。不确定JPA是否指示此行为,或者它是否特定于Hibernate或MySQL。)

+1…除非您使用的是容器管理的持久性上下文(OP没有)我的是一个独立的应用程序,所以我不知道如何管理它,我们似乎有一个泄漏,不管我是否添加em.close()调用,连接泄漏仍然存在,不管我是否关闭EntityManager
public static void rollbackAndClose(EntityManager mgr) {
    if (mgr != null) {
        EntityTransaction transaction = mgr.getTransaction();
        if (transaction.isActive()) {
            transaction.rollback();
        }
        mgr.close();
    }
}