gpt4 book ai didi

java - 为什么 Spring 在使用 Hibernate 3 时延迟关闭 Hibernate session

转载 作者:行者123 更新时间:2023-12-03 23:11:09 26 4
gpt4 key购买 nike

背景:

我正在努力将我们产品中使用的 Hibernate 3 升级到 Hibernate 4。我们使用的 Spring 版本是 Spring 3.2,我们的代码大量使用了 Spring 3.2 的 HibernateTemplateorg.springframework.orm 包不支持它。 hibernate4 了。作为第一步,我的任务是编写 HibernateTemplate 的自定义版本,它使用 SessionFactory 获取 session 并删除 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 会延迟关闭 session ?

2) 如果我在 org.springframework.orm.hibernate4 中使用 Hibernate 4 session 和类,是否还需要执行延迟关闭?

最佳答案

Hibernate 不会关闭 session 。由调用者关闭 session 。在这种情况下,调用者是 spring,这取决于您如何设置事务管理。

Spring 将在您的事务提交时关闭 session ,或者可选地(如果您配置正确)在 Web 请求完成时关闭 session 。

如果您没有任何事务管理设置,模板将在执行您传递给它的回调后立即关闭 session 。

您在 HolderMap 中看到的是该事务管理的一部分。

PS:HibernateTemplate 在 hibernate4 包中消失了,但在 spring 4 中卷土重来。在 spring 3 中执行 hibernate 4 的首选方法是使用 SessionFactory.getCurrentSession( ),让spring的事务支持管理 session 的开启和关闭。恕我直言,当他们这样做时这是一个巨大的错误,但至少他们已经回溯了。

关于java - 为什么 Spring 在使用 Hibernate 3 时延迟关闭 Hibernate session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25734741/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com