Hibernate + PostgreSQL - 连接状态显示 "在事务中处于空闲状态"

9

我有一个在Tomcat上运行使用Hibernate的JSF应用程序。 我进行了一个小测试,发现了问题 - 创建了一个servlet,它唯一的作用是:

EntityManager em=null;
try {
    em = ConnectDb.getEntityManager();
    em.createQuery("from Frete").getResultList();
} catch (Exception e) {
    e.printStackTrace();
} finally {
    try{em.close();}catch(Exception ex){}
}

如果我在pg_admin中执行以下SQL语句,我将得到一条记录,在“query”列中,我可以看到由Hibernate执行的SQL语句,而在“state”列中,则显示“idle in transaction”。
但问题是,并没有开始任何事务,我所做的唯一一件事就是创建一个查询。而EntityManager已经关闭 - 在关闭时没有抛出任何异常。
也许这是在persistence.xml中的配置问题,但我不知道。这是我的persistence.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="GestaoPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
      <property name="hibernate.connection.autocommit" value="false"/>
      <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost/AtualyGestao"/>
      <property name="javax.persistence.jdbc.password" value="atg4747"/>
      <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
      <property name="javax.persistence.jdbc.user" value="AtualyGestao"/>
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
      <property name="hibernate.format_sql" value="false"/>
      <property name="hibernate.connection.encoding" value="ISO-8859-1"/>
    </properties>
  </persistence-unit>
</persistence>
3个回答

3

我所做的唯一一件事就是创建一个查询

看起来你也执行了它:

em.createQuery("from Frete").getResultList();

当你执行这行代码时:Hibernate会执行查询,为此PostgreSQL驱动程序会创建一个事务。

由于自动提交被设置为false:

  <property name="hibernate.connection.autocommit" value="false"/>

那么交易并没有提交,这就是你收到这条消息的原因。 顺便说一下:不要使用


try{em.close();}catch(Exception ex){}

请写下以下内容:

try{em.close();}catch(Exception ex){ex.printStacktrace();}

我尝试过了。在关闭EntityManager时没有抛出任何异常。如果我手动开始一个事务并提交它,连接将保留在数据库中,但处于IDLE状态。但预期的行为是连接应该从数据库中消失。我尝试使用java.sql.Connection进行操作,使用默认的JDBC Connection,它按预期工作,只有Hibernate会出现这种情况。 - Mateus Viccari
这是我创建的一个旧线程,但现在我已经找到了解决方案,我刚刚开始使用c3p0与Hibernate一起管理连接,因此如果在我的代码中我忘记关闭连接,c3p0将在一段时间后自动关闭它。 - Mateus Viccari

1

我知道这是一个非常老的帖子。写下我的解决方案只是为了帮助那些目前遇到此问题的人。我最近也遇到了这个问题。当我进行更多调试时,我发现即使在选择查询的情况下,Hibernate 也会自动创建事务。而且它没有正确地提交/回滚查询。因此,我明确地添加了启动和停止事务的代码,这解决了这个问题。所以代码看起来像这样:

    SessionPersister session = CommonSessionPersisterFactory.INSTANCE.openSession(); 
    Transaction transaction = null;
    try {       
        transaction = session.beginTransaction();
        //do the query or update.

        transaction.commit();
    }
    catch(Exception re){
        transaction.rollback();
    }
    finally {
        if(session != null){
            Transaction tran = session.getTransaction();
            if(tran != null && tran.isActive() && !tran.wasCommitted() && tran.wasRolledBack()){
                tran.rollback();
            }
            session.close();
        }

在最后的 if 语句中,你不是应该使用 !tran.wasRolledBack() 吗? - davemyron

0

我在多个地方也遇到了这个问题。后来用JDBC替换了Hibernate,再也没有遇到这个问题了!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接