现在我已经开发了一个遗留的web项目,使用了spring mvc(spring 4.0.5)和hibernate(3.3.2 GA),我发现了一些服务并且dao明确地关闭了session,例如。
public City getCityByCityId(Integer cityId) {
Session s = HibernateSessionFactory.getSession();
City city = cityDAO.getById(City.class, cityId, s);
s.close(); // after getting the result explicitly close the session
return city;
}
但其他人没有,会话被放在threadLocal中。
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
// build session
threadLocal.set(session);
}
return session;
}
另外我在过滤器中发现,在调用chain.doFilter(...)
之后,仍然会调用close glob session,例如。
try {
chain.doFilter(request, response);
} catch (Exception e) {
//......
}
try{
//avoid forgettig to close session
HibernateSessionFactory.closeSession();
}catch(Exception e){
log.error("close session in filter failed",e);
}
现在我遇到了下面的问题,就是当我调用一个查询方法(它明确地关闭会话)时,例如。
Session s = HibernateSessionFactory.getSession();
Transaction beginTransaction = s.beginTransaction();
try {
usOrderDAO.save(order, s);
City city = cityService.getCityByCityId(order.getCity()); // in this query it will close session
addOrderBusinessDistricts(order, city, s);
//...
beginTransaction.commit();
} catch (Exception e) {
//...
} finally {
s.close();
}
它会抛出异常:
org.hibernate.SessionException: Session is closed!
at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:72)
at org.hibernate.impl.SessionImpl.createSQLQuery(SessionImpl.java:1655)
原因是在执行commit之前关闭会话。
所以现在为了解决我的上述问题,我想删除所有那些服务和dao中的s.close();
代码,无论如何最终在过滤器中它会关闭会话。但我不确定是否会引起一些潜在的错误。如何评估风险?