浏览 2615 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-03-04
LazyInitializationException(Part2) Spring, Springmodules, JBPM持久化集成理解系列三 【本系列如需转载,请注明作者及出处】 到此,如果有朋友还是比较清醒的话,应该还会有疑问,在OpenSessionInViewFilter里如果是isSingleSession为true,并没有看到session的关闭,到底是在什么地方关闭了呢?它其实是在OpenSessionInViewInterceptor里关闭了的。
public void afterCompletion(WebRequest request, Exception ex) throws DataAccessException { String participateAttributeName = getParticipateAttributeName(); Integer count = (Integer) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST); if (count != null) { // Do not modify the Session: just clear the marker. if (count.intValue() > 1) { request.setAttribute(participateAttributeName, new Integer(count.intValue() - 1), WebRequest.SCOPE_REQUEST); } else { request.removeAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST); } } else { if (isSingleSession()) { // single session mode SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(getSessionFactory()); logger.debug("Closing single Hibernate Session in OpenSessionInViewInterceptor"); SessionFactoryUtils.closeSession(sessionHolder.getSession()); } else { // deferred close mode SessionFactoryUtils.processDeferredClose(getSessionFactory()); } } }
总结一下: OpenSessionInViewFilter首先会确保sessionFactory的存在, 如果启用了session延迟关闭策略,也就是isSingleSession为false,session的创建和打开会在HibernateTemplate的execute里发生,而关闭会统一在OpenSessionInViewFilter返回时。 如果isSingleSession为true时,session的打开会在OpenSessionInViewFilter里或者之前的某个时候,而关闭会在OpenSessionInViewInterceptor里。 这样我们就可用自己在Junit或者其他应用场景使用延迟关闭策略来使我们的程序收益。以下附带前面篇章提及到的BaseTestCase,如果存在SessionFactory,则激活延迟关闭session策略。各位可用参考使用。
package com.cabernet; 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.dao.DataAccessResourceFailureException; import org.springframework.orm.hibernate3.SessionFactoryUtils; import org.springframework.orm.hibernate3.SessionHolder; import org.springframework.test.AbstractDependencyInjectionSpringContextTests; import org.springframework.transaction.support.TransactionSynchronizationManager; /** * Supports OpenSessionInViewFilter like Hibernate Lazy-loading when * SessionFactory is present * * @author ginge * * @see OpenSessionInViewFilter */ public class BaseTestCase extends AbstractDependencyInjectionSpringContextTests { protected Log log = LogFactory.getLog(this.getClass()); private FlushMode flushMode = FlushMode.MANUAL; protected SessionFactory sessionFactory; @Override protected void prepareTestInstance() throws Exception { // TODO Auto-generated method stub super.prepareTestInstance(); if (isSessionFactoryPresent()) { afterSessionFactorySet(); SessionFactoryUtils.initDeferredClose(sessionFactory); TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(this.getSession())); } } @Override protected void onTearDown() throws Exception { // TODO Auto-generated method stub if (isSessionFactoryPresent()) { SessionFactoryUtils.processDeferredClose(sessionFactory); TransactionSynchronizationManager.unbindResource(sessionFactory); } super.onTearDown(); } private boolean isSessionFactoryPresent() { return this.sessionFactory != null; } protected void afterSessionFactorySet() { } public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override protected String[] getConfigLocations() { return new String[] { "classpath*:applicationContext-resources.xml" }; } protected Session getSession() throws DataAccessResourceFailureException { Session session = SessionFactoryUtils.getSession(sessionFactory, true); FlushMode flushMode = getFlushMode(); if (flushMode != null) { session.setFlushMode(flushMode); } return session; } private FlushMode getFlushMode() { return this.flushMode; } }
到了这个时刻,我们回到Jbpm跟Springmodules, Spring的持久化集成上来,虽然Jbpm本身提供了JbpmContextFilter,它的功能是在Filter开始打开JbpmContext,Filter返回时关闭JbpmContext。但是在前面的篇章中,我们知道JbpmTemplate中会在操作开始前注入session。因此,使用了OpenSessionInViewFilter和JbpmTemplate之后,JbpmContextFilter将会英雄无用武之地。这个OpenSessionInViewFilter必须配置在其他Filter之前以确保在进入其他Filter之前激活延迟关闭策略或者绑定Session到当前线程中。
(完结) 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |