hibernate3+spring2.0 + OpenSessionInViewFilter

spring2.0和hibernate3.0整合存在挺多问题,其中ASM.jar包的版本冲突暂且不说,就光一个OpenSessionInViewFilter就够恶心人了。今天终于把它搞定了。按照原始的事务声明和配置形式对于spring2.0+hibernate3.0+OpenSessionInVewFilter已经不生效了,因为spring2.0里面的OpenSessionInViewFilter的getSession方法中会对session的flushMode设定一个默认为NEVER的值,而这个值在hibernate3.0似乎是不能理解的。
   所以一旦你使用默认形式去管理session就会出一个

Java代码 复制代码
  1. Write operations are not allowed in read-only mode(FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition

 的异常。产生的原因就是和session的flushMode有关系,我们来看一下OpenSessionInViewFilter这个类里面的getSession方法

Java代码 复制代码

  1. protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {      
  2.         Session session = SessionFactoryUtils.getSession(sessionFactory, true);     
  3.         FlushMode flushMode = getFlushMode();      
  4.         if (flushMode != null) {      
  5.             session.setFlushMode(flushMode);      
  6.         }      
  7.         return session;      
  8.     }  
 

这里面FlushMode flushMode = getFlushMode(); 得到的flushMode就是NEVER然后再扔到session 里面当然不行喽,解决办法就是继承OpenSessionInViewFilter类,然后重写这个方法,加句 this.setFlushMode(FlushMode.AUTO);或者干脆把session里面直接扔个FlushMode.AUTO,然后再重写一个叫closeSession的方法,记住一定要重写,因为增加了flushMode以后要调用session.flush()才可以正常提交数据,其实重写closeSession就是为了加1句session.flush(),然后下面调用super.closeSession()方法就行了。

 

  <aop:config proxy-target-class="true">
        <aop:pointcut id="managerOperation" expression="execution(* com.yyii.eip..service.*Manager.*(..))"/> 
        <aop:advisor advice-ref="txAdvice" pointcut-ref="managerOperation"/>
    </aop:config>

<!-- 基本事务定义 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
            <tx:method name="save*"/>
            <tx:method name="update*"/>
            <tx:method name="remove*"/>
            <tx:method name="delete*"/>
            <tx:method name="create*"/>
            <!-- other methods are set to read only --> 
            <tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
如果把proxy-target-class="true"去掉, 不会报warn
但如果写上proxy-target-class="true", 2.0的配置依然会报WARN

 // 这样就可以了
getHibernateTemplate().setFlushMode(getHibernateTemplate().FLUSH_AUTO

posted @ 2009-03-08 00:23  QQ天堂  阅读(1291)  评论(0编辑  收藏  举报