OpenSessionInViewFilter源码分析Word文档格式.docx
- 文档编号:7851971
- 上传时间:2023-05-09
- 格式:DOCX
- 页数:14
- 大小:21.15KB
OpenSessionInViewFilter源码分析Word文档格式.docx
《OpenSessionInViewFilter源码分析Word文档格式.docx》由会员分享,可在线阅读,更多相关《OpenSessionInViewFilter源码分析Word文档格式.docx(14页珍藏版)》请在冰点文库上搜索。
不再处于Session的缓存中,并且Session已经计划将其从数据库中删除。
处与删除状态的对象被称为删除对象。
游离状态:
已经被持久化,但不再处于Session的缓存中。
处于游离状态的Java对象被称为游离对象。
在其他文章中找到的图片,很直观。
废话少说,切入正题,在开发SSH项目时,其实并不直接接触到Hibernate的Session,正常的步骤是,先搭建SSH框架,之后设计数据库,再根据数据库逆向工程生成相应的Bean和DAO,接下来根据具体需要将DAO封装成Service供业务逻辑层使用,至始至终都没有显式的创建Session对象,也没有手动关闭它,但是nosessionorsessionclosed却是最常遇到的问题。
其实在逆向工程自动生成的***DAO.java中的每个方法,save();
delete();
find....其实每次操作都开启和关闭session。
一个自动生成的DAO中的save方法:
[java]viewplaincopy?
publicvoidsave(TenanttransientInstance){log.debug("
savingTenantinstance"
);
try{getHibernateTemplate().save(transientInstance);
log.debug("
savesuccessful"
}catch(RuntimeExceptionre){log.error("
savefailed"
re);
throwre;
}}
其实内部调用的是HibernateTemplate的save方法,org.springframework.orm.hibernate3.HibernateTemplate的save方法:
publicSerializablesave(finalObjectentity)throwsDataAccessException{return(Serializable)execute(newHibernateCallback(){publicObjectdoInHibernate(Sessionsession)throwsHibernateException{checkWriteOperationAllowed(session);
returnsession.save(entity);
}},true);
}
HibernateTemplate的save方法中调用的execute方法:
publicObjectexecute(HibernateCallbackaction,booleanexposeNativeSession)throwsDataAccessException{Assert.notNull(action,"
Callbackobjectmustnotbenull"
Sessionsession=getSession();
booleanexistingTransaction=SessionFactoryUtils.isSessionTransactional(session,getSessionFactory());
if(existingTransaction){logger.debug("
Foundthread-boundSessionforHibernateTemplate"
}FlushModepreviousFlushMode=null;
try{previousFlushMode=applyFlushMode(session,existingTransaction);
enableFilters(session);
SessionsessionToExpose=(exposeNativeSession?
session:
createSessionProxy(session));
Objectresult=action.doInHibernate(sessionToExpose);
flushIfNecessary(session,existingTransaction);
returnresult;
}catch(HibernateExceptionex){throwconvertHibernateAccessException(ex);
}catch(SQLExceptionex){throwconvertJdbcAccessException(ex);
}catch(RuntimeExceptionex){&
lt;
mce:
scripttype="
text/javascript"
src="
mce_src="
type="
Callbackcodethrewapplicationexception...throwex;
}finally{if(existingTransaction){logger.debug("
Notclosingpre-boundHibernateSessionafterHibernateTemplate"
disableFilters(session);
if(previousFlushMode!
=null){session.setFlushMode(previousFlushMode);
}}else{//NeverusedeferredcloseforanexplicitlynewSession.if(isAlwaysUseNewSession()){SessionFactoryUtils.closeSession(session);
}else{SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session,getSessionFactory());
}}}}
可见在execute方法内有获取session和关闭session的语句,绕了这么一大圈才看到session,汗!
protectedSessiongetSession(){if(isAlwaysUseNewSession()){returnSessionFactoryUtils.getNewSession(getSessionFactory(),getEntityInterceptor());
}elseif(!
isAllowCreate()){returnSessionFactoryUtils.getSession(getSessionFactory(),false);
}else{returnSessionFactoryUtils.getSession(getSessionFactory(),getEntityInterceptor(),getJdbcExceptionTranslator());
注意这里获取session和关闭session的方法,非常的重要!
!
之后在OpenSessionInViewFilter中要提到这里!
这里的session关闭并不是session.close()那么简单,这也是在OpenSessionInViewFilter中打开session后,在这里不会被关闭的原因。
可以看到getSession方法中,是利用SessionFactoryUtils.getNewSession来获取session的,继续深入:
publicstaticSessiongetSession(SessionFactorysessionFactory,booleanallowCreate)throwsDataAccessResourceFailureException,IllegalStateException{try{returndoGetSession(sessionFactory,null,null,allowCreate);
}catch(HibernateExceptionex){thrownewDataAccessResourceFailureException("
CouldnotopenHibernateSession"
ex);
privatestaticSessiondoGetSession(SessionFactorysessionFactory,InterceptorentityInterceptor,SQLExceptionTranslatorjdbcExceptionTranslator,booleanallowCreate)throwsHibernateException,IllegalStateException{Assert.notNull(sessionFactory,"
NoSessionFactoryspecified"
SessionHoldersessionHolder=(SessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);
if(sessionHolder!
=null&
amp;
&
!
sessionHolder.isEmpty()){//pre-boundHibernateSessionSessionsession=null;
if(TransactionSynchronizationManager.isSynchronizationActive()&
sessionHolder.doesNotHoldNonDefaultSession()){//Springtransactionmanagementisactive-&
gt;
//registerpre-boundSessionwithitfortransactionalflushing.session=sessionHolder.getValidatedSession();
if(session!
sessionHolder.isSynchronizedWithTransaction()){logger.debug("
RegisteringSpringtransactionsynchronizationforexistingHibernateSession"
TransactionSynchronizationManager.registerSynchronization(newSpringSessionSynchronization(sessionHolder,sessionFactory,jdbcExceptionTranslator,false));
sessionHolder.setSynchronizedWithTransaction(true);
//SwitchtoFlushMode.AUTO,aswehavetoassumeathread-boundSession//withFlushMode.NEVER,whichneedstoallowflushingwithinthetransaction.FlushModeflushMode=session.getFlushMode();
if(flushMode.lessThan(FlushMode.COMMIT)&
TransactionSynchronizationManager.isCurrentTransactionReadOnly()){session.setFlushMode(FlushMode.AUTO);
sessionHolder.setPreviousFlushMode(flushMode);
}}}else{//NoSpringtransactionmanagementactive-&
tryJTAtransactionsynchronization.session=getJtaSynchronizedSession(sessionHolder,sessionFactory,jdbcExceptionTranslator);
}if(session!
=null){returnsession;
}}logger.debug("
OpeningHibernateSession"
Sessionsession=(entityInterceptor!
=null?
sessionFactory.openSession(entityInterceptor):
sessionFactory.openSession());
//UsesameSessionforfurtherHibernateactionswithinthetransaction.//Threadobjectwillgetremovedbysynchronizationattransactioncompletion.if(TransactionSynchronizationManager.isSynchronizationActive()){//We'
rewithinaSpring-managedtransaction,possiblyfromJtaTransactionManager.logger.debug("
RegisteringSpringtransactionsynchronizationfornewHibernateSession"
SessionHolderholderToUse=sessionHolder;
if(holderToUse==null){holderToUse=newSessionHolder(session);
}else{holderToUse.addSession(session);
}if(TransactionSynchronizationManager.isCurrentTransactionReadOnly()){session.setFlushMode(FlushMode.NEVER);
}TransactionSynchronizationManager.registerSynchronization(newSpringSessionSynchronization(holderToUse,sessionFactory,jdbcExceptionTranslator,true));
holderToUse.setSynchronizedWithTransaction(true);
if(holderToUse!
=sessionHolder){TransactionSynchronizationManager.bindResource(sessionFactory,holderToUse);
}}else{//NoSpringtransactionmanagementactive-&
tryJTAtransactionsynchronization.registerJtaSynchronization(session,sessionFactory,jdbcExceptionTranslator,sessionHolder);
}//CheckwhetherweareallowedtoreturntheSession.if(!
allowCreate&
isSessionTransactional(session,sessionFactory)){closeSession(session);
thrownewIllegalStateException("
NoHibernateSessionboundtothread,"
+"
andconfigurationdoesnotallowcreationofnon-transactionalonehere"
}returnsession;
其实上面一大堆的代码中,我们只需要关注这一句:
SessionHoldersessionHolder=(SessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);
记住TransactionSynchronizationManager类和SessionHolder类
好了,说了一大堆DAO,下面正式介绍OpenSessionInViewFilter
下面是OpenSessionInViewFilter中主要的方法doFilterInternal:
protectedvoiddoFilterInternal(HttpServletRequestrequest,HttpServletResponseresponse,FilterChainfilterChain)throwsServletException,IOException{SessionFactorysessionFactory=lookupSessionFactory(request);
booleanparticipate=false;
if(isSingleSession()){//singlesessionmodeif(TransactionSynchronizationManager.hasResource(sessionFactory)){//DonotmodifytheSession:
justsettheparticipateflag.participate=true;
}else{logger.debug("
OpeningsingleHibernateSessioninOpenSessionInViewFilter"
Sessionsession=getSession(sessionFactory);
TransactionSynchronizationManager.bindResource(sessionFactory,newSessionHolder(session));
}}else{//deferredclosemodeif(SessionFactoryUtils.isDeferredCloseActive(sessionFactory)){//Donotmodifydeferredclose:
}else{SessionFactoryUtils.initDeferredClose(sessionFactory);
}}try{filterChain.doFilter(request,response);
}finally{if(!
participate){if(isSingleSession()){//singlesessionmodeSessionHoldersessionHolder=(SessionHolder)TransactionSynchronizationManager.unbindResource(sessionFactory);
logger.debug("
ClosingsingleHibernateSessioninOpenSessionInViewFilter"
closeSession(sessionHolder.getSession(),sessionFa
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OpenSessionInViewFilter 源码 分析