Spring, Springmodules, JBPM持久化集成--摆脱
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到当前线程中。
(完结)
分享到:
- 2008-03-04 23:45
- 浏览 1486
- 评论(1)
- 论坛回复 / 浏览 (0 / 2615)
- 查看更多
相关推荐
spring-modules-jbpm31-0.6.jar,spring整合jbpm的jar包
Spring-Jbpm-JSF-Example.pdf
jbpm-jpdl-suite-3.2GA -(5)分开压缩(共5个文件)jbpm下载 jbpm-jpdl-suite-3.2GA -(5)分开压缩(共5个文件)jbpm下载
JBPM-----PPT 工作流JBPM完整PPT文件。帮你更快速上手。
jbpm-starters-kit-3.1.2插件,jbpm-starters-kit-3.1.2插件,jbpm-starters-kit-3.1.2插件,jbpm-starters-kit-3.1.2插件,jbpm-starters-kit-3.1.2插件,jbpm-starters-kit-3.1.2插件,共两卷
jbpm-jpdl-designer-site-3.1.7.zip jbpm-jpdl-designer-site-3.1.7.zip jbpm-jpdl-designer-site-3.1.7.zip
jbpm-jpdl-suite-3.2.3.zipjbpm-jpdl-suite-3.2.3.zipjbpm-jpdl-suite-3.2.3.zipjbpm-jpdl-suite-3.2.3.zipjbpm-jpdl-suite-3.2.3.zipjbpm-jpdl-suite-3.2.3.zipjbpm-jpdl-suite-3.2.3.zipjbpm-jpdl-suite-3.2.3....
jbpm-jpdl-suite-3.2.GA.zip
jbpm-workitems-5.1.0.Final-sources.jar jbpm5 源码
jbpm-bpmn2-5.1.0.Final.jar jbpm5
jbpm-jpdl-suite-3.2.GA.zip
jbpm-flow-builder-5.1.0.Final.jar jbpm5
jbpm-eclipse插件,这个插件随jbpm4.4 一起发布,位于 jbpm-4.4/install/src/gpd 目录下,由于许多人找不到这个包,所有传上来,赚点积分。
jbpm-jpdl-suite-3.2.GA.zip
jbpm-jpdl-designer资源
jbpm-starters-kit-3.1.2.zip官方下载地址 版本里包括一个JBPM流程设计器的Eclipse插件,和一个用JBOSS作为服务器的示例流程等相关文件。解压jbpm-starters-kit-3.1.2.rar到某个特定目录,这里我们首先用到的是包里...
jbpm-installer-3.2.6.GA.jar
jbpm-jpdl-suite-3.2.3安装配置.doc
jbpm-starters-kit-3.1.2.插件,jbpm-starters-kit-3.1.2.插件,jbpm-starters-kit-3.1.2.插件,jbpm-starters-kit-3.1.2.插件,jbpm-starters-kit-3.1.2.插件,jbpm-starters-kit-3.1.2.插件,jbpm-starters-kit-...