好的,这就是我实际所做的,我不知道这是否是解决此问题的最佳解决方案,但在我们的情况下,并且由于我一直在寻找最本地化的解决方案,因此对我来说似乎是最好的。
我扩展了 springframework.orm.hibernate3.HibernateTemplate 并创建了一个新的 MyHibernateTemplate。新模板的主要作用是覆盖大多数 hibernate3.HibernateTemplate 最终导致的 doExecute 方法,并提供旧 SessionFactoryUtils 提供的一些功能(如 isSessionTransactional 和 applyTransactionTimeout)。
新的 doExecute 复制了旧的逻辑,但不是 SessionFactoryUtils.getNewSession 来获取会话,而是首先尝试查找打开的会话 getSessionFactory().getCurrentSession() :
boolean newSessionOpened = false;
Session session;
if (enforceNewSession){
session = SessionFactoryUtils.openSession(getSessionFactory());
newSessionOpened = true;
} else {
try {
// look for an open session
session = getSessionFactory().getCurrentSession();
}
catch (HibernateException ex) {
try {
// if there isn't an open session, open one yourself
session = getSessionFactory().openSession();
newSessionOpened = true;
} catch (HibernateException e) {
throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);
}
}
}
// is the open session, is a session in a current transaction?
boolean existingTransaction = (!enforceNewSession &&
(!isAllowCreate() || isSessionTransactional(session, getSessionFactory())));
您只需要手动关闭此会话:
finally {
// if session was used in an existing transaction restore old settings
if (existingTransaction) {
//logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
disableFilters(session);
if (previousFlushMode != null) {
session.setFlushMode(previousFlushMode);
}
}
// if not and a new session was opened close it
else {
// Never use deferred close for an explicitly new Session.
if (newSessionOpened) {
SessionFactoryUtils.closeSession(session);
//_log.info("Closing opened Hibernate session");
}
}
我试图保持这个答案简短,但如果有任何问题,我可以进一步详细说明这个问题。