Hibernate - 获取查询后会话关闭

时间:2014-08-01 20:20:52

标签: java sql hibernate session

我有一个所有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逻辑类:

public class HibCentral {

    ....other methods....

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

但这产生了相同的"会话已关闭"错误。

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

2 个答案:

答案 0 :(得分:1)

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

解决方案:将@Transactional注释移至更高级别。这通常应该在服务层。如果服务层中的类在彼此之间进行交互,则将@Transactional移动到更高级别,以避免打开和关闭多个连接。

答案 1 :(得分:0)

使用@Transactional时,除非您指定@Transactional(propagation=Propagation.REQUIRED),否则它将应用于方法。

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

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

干杯!!