我有一个所有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();
}
}
但这产生了相同的"会话已关闭"错误。
我该怎么做才能使这项工作?
答案 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();
}
干杯!!