【问题标题】:Hibernate - Session closed after getting queryHibernate - 获取查询后关闭会话
【发布时间】:2014-08-01 20:20:51
【问题描述】:

我有一个用于所有 Hibernate 逻辑的中心类(大部分我没有编写)。我们就叫它HibCentral吧。

我的代码使用这个类从 SQL 字符串创建查询:

public class HibCentral {

    ...some hibernate setup and other methods...

    @Transactional
    public Query createSQLQuery(final String sql) {
        return getCurrentSession().createSQLQuery(sql);
    }
}

getCurrentSession() 只是调用sessionFactory.getCurrentSession()

我的课程(我们称之为MyClass)由高级服务(Service)调用。它获取一个 SQL 字符串,调用此方法以获取查询,填充其参数,并将其发送回服务。然后服务使用query.list() 调用查询。

public class MyClass {
    public Query getQuery(Args args) {
        Query q = hibCentral.createSQLQuery(getSQLString());
        setParameters(q);
        return q;
    }
}

public class Service {
    public void doIt() {
        Query q = myClass.getQuery(args);
        // some logic
        List list = q.list();
    }
}

但是等等,会话已关闭。

我也尝试将 list() 调用移至 Hibernate-logic 类:

public class HibCentral {

    ....other methods....

    @Transactional
    public List list(final Query query) {
        return query.list();
    }
}

但这会产生相同的“会话已关闭”错误。

我该怎么做才能完成这项工作?

【问题讨论】:

  • 实际错误在哪里抛出?是在会话关闭时还是在您致电list() 时?

标签: java sql hibernate session


【解决方案1】:

问题是只有HibCentral 类中的方法是事务性的,这意味着数据库连接打开和关闭仅用于执行这些方法。之后,连接将关闭,并且在这些方法之外与 Query 等 Hibernate 元素的任何交互都将没有有效的连接,您将收到这些错误。

解决方法:将@Transactional注解移到更高级别。这通常应该在服务层。如果您在服务层中的类之间相互交互,则将@Transactional 移至更高级别,以避免打开和关闭许多连接。

【讨论】:

    【解决方案2】:

    当您使用@Transactional 时,它适用于方法,除非您指定@Transactional(propagation=Propagation.REQUIRED)

    只要方法调用完成,事务就会关闭,因此会话。您应该创建查询获取列表并以相同的方法返回。

    @Transactional
        public List createSQLQuery(final String sql) {
            Query query = getCurrentSession().createSQLQuery(sql);
            return q.list();
        }
    

    干杯!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-19
      • 2012-12-19
      • 1970-01-01
      相关资源
      最近更新 更多