【发布时间】:2014-09-08 23:46:23
【问题描述】:
背景:
我正在努力将我们产品中使用的 Hibernate 3 升级到 Hibernate 4。我们使用的 Spring 版本是 Spring 3.2,并且我们的代码大量使用 Spring 3.2 的 HibernateTemplate,而 org.springframework.orm 包不支持它。 hibernate4 了。作为第一步,我的任务是编写一个自定义版本的 HibernateTemplate,它使用 SessionFactory 来获取会话并删除 Hibernate 3 的所有依赖项。
问题:
当我阅读Spring 3.2的源码时,我注意到org.springframework.orm.hibernate3中的许多API在org.springframework.orm.hibernate4中被删除了.其中一种情况是 org.springframework.orm.hibernate3 包的 SessionFactoryUtils 中的 closeSessionOrRegisterDeferredClose 方法。
/**
* 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 会话和类,是否还需要关闭延迟?
【问题讨论】: