org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session was closed 错误的解决办法
以下内容转自:
http://www.javaeye.com/topic/14631
众所周知, 为了解决 Hibernate Lazy 问题, Spring 中引入了 OpenSessionInViewInterceptor, 这样虽然解决了页面上的 Lazy Load 问题,却增加了各层之间的偶合性, 如果一个 Lazy 的 Collection 在页面上可以被正确的 load, 但是如果请求不是来自于 HttpServletRequest (比如在 TestCase 或 Service 中希望获取 lazy 的属性), 一般会导致两种错误:
Java代码
1. 设置了 lazy = "true"
会导致 org.hibernate.LazyInitializationException: failed to lazily initialize a collection of xxx: xxx - no session or session was closed
2. 设置里 lazy = "false"
会导致 org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session was closed
为了方便测试, 灵活使用 lazy load, 我按照 OpenSessionInViewInterceptor 的思路实现了一个 HibernateLazyResolber, 代码如下:
package org.summerfragrance.support.hibernate3; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.FlushMode; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.orm.hibernate3.SessionFactoryUtils; import org.springframework.orm.hibernate3.SessionHolder; import org.springframework.transaction.support.TransactionSynchronizationManager; public class HibernateLazyResolver implements InitializingBean { private static Log logger = LogFactory.getLog(HibernateLazyResolver.class);; private boolean singleSession = true; private SessionFactory sessionFactory; boolean participate = false; protected Session session = null; public final void setSessionFactory(SessionFactory sessionFactory); { this.sessionFactory = sessionFactory; } public void setSingleSession(boolean singleSession); { this.singleSession = singleSession; } protected boolean isSingleSession(); { return singleSession; } public void afterPropertiesSet(); throws Exception { if (sessionFactory == null); { throw new IllegalArgumentException("SessionFactory is reqirued!");; } } public void openSession(); { if (isSingleSession();); { // single session mode if (TransactionSynchronizationManager.hasResource(sessionFactory);); { // Do not modify the Session: just set the participate flag. participate = true; } else { logger.debug("Opening single Hibernate Session in HibernateLazyResolver");; session = getSession(sessionFactory);; TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session););; } } else { // deferred close mode if (SessionFactoryUtils.isDeferredCloseActive(sessionFactory);); { // Do not modify deferred close: just set the participate flag. participate = true; } else { SessionFactoryUtils.initDeferredClose(sessionFactory);; } } } |