背景:
我正在升级我们产品中使用的Hibernate 3到Hibernate 4。我们使用的Spring版本是Spring 3.2,我们的代码大量使用了Spring 3.2的HibernateTemplate,但是在org.springframework.orm.hibernate4包中不再支持它。作为第一步,我的任务是编写一个自定义版本的HibernateTemplate,它使用SessionFactory来获取session并移除所有Hibernate 3的依赖。
问题:
当我阅读Spring 3.2的源代码时,我注意到org.springframework.orm.hibernate3中的许多API在org.springframework.orm.hibernate4中被删除。其中一个例子是SessionFactoryUtils中的closeSessionOrRegisterDeferredClose方法,在org.springframework.orm.hibernate3包中。
/**
* Close the given Session or register it for deferred close.
* @param session the Hibernate Session to close
* @param sessionFactory Hibernate SessionFactory that the Session was created with
* (may be {@code null})
* @see #initDeferredClose
* @see #processDeferredClose
*/
static void closeSessionOrRegisterDeferredClose(Session session, SessionFactory sessionFactory) {
Map<SessionFactory, Set<Session>> holderMap = deferredCloseHolder.get();
if (holderMap != null && sessionFactory != null && holderMap.containsKey(sessionFactory)) {
logger.debug("Registering Hibernate Session for deferred close");
// Switch Session to FlushMode.MANUAL for remaining lifetime.
session.setFlushMode(FlushMode.MANUAL);
Set<Session> sessions = holderMap.get(sessionFactory);
sessions.add(session);
}
else {
closeSession(session);
}
}
这个方法被 HibernateTemplate 类的 doExecute 方法调用(代码的最后一行)。
/**
* Execute the action specified by the given action object within a Session.
* @param action callback object that specifies the Hibernate action
* @param enforceNewSession whether to enforce a new Session for this template
* even if there is a pre-bound transactional Session
* @param enforceNativeSession whether to enforce exposure of the native
* Hibernate Session to callback code
* @return a result object returned by the action, or {@code null}
* @throws org.springframework.dao.DataAccessException in case of Hibernate errors
*/
protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNewSession, boolean enforceNativeSession)
throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Session session = (enforceNewSession ?
SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()) : getSession());
boolean existingTransaction = (!enforceNewSession &&
(!isAllowCreate() || SessionFactoryUtils.isSessionTransactional(session, getSessionFactory())));
if (existingTransaction) {
logger.debug("Found thread-bound Session for HibernateTemplate");
}
FlushMode previousFlushMode = null;
try {
previousFlushMode = applyFlushMode(session, existingTransaction);
enableFilters(session);
Session sessionToExpose =
(enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session));
T result = action.doInHibernate(sessionToExpose);
flushIfNecessary(session, existingTransaction);
return result;
}
catch (HibernateException ex) {
throw convertHibernateAccessException(ex);
}
catch (SQLException ex) {
throw convertJdbcAccessException(ex);
}
catch (RuntimeException ex) {
// Callback code threw application exception...
throw ex;
}
finally {
if (existingTransaction) {
logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
disableFilters(session);
if (previousFlushMode != null) {
session.setFlushMode(previousFlushMode);
}
}
else {
// Never use deferred close for an explicitly new Session.
if (isAlwaysUseNewSession()) {
SessionFactoryUtils.closeSession(session);
}
else {
SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory());
}
}
}
}
org.springframework.orm.hibernate4包中仍然有SessionFactoryUtils类,但closeSessionOrRegisterDeferredClose方法已被删除。
问题:
我想知道:
1) 在哪些情况下Hibernate 3会推迟关闭会话?
2) 如果我在org.springframework.orm.hibernate4中使用Hibernate 4会话和类,是否仍需要进行延迟关闭?
HibernateTemplate
,因为它的应用情况已经不存在了(自从Hiberate 3.0.1引入CurrentSessionContext
后,该模板基本上是为了弥补没有它而提供的解决方法,在hibernate2中,它提供了有价值的异常翻译。现在可以通过更好的方式解决所有这些问题,从而使应用程序更清洁,即减少对Spring API的依赖)。 - M. DeinumHibernateTemplate
的最小化版本,作为围绕sessionFactory.getCurrentSession
的简单包装器。 - M. Deinum