为了解决hibernate的懒加载问题,我在项目中引入了Spring提供的OpenSessionInViewFilter(引入时已经重写了)。
引入OpenSessionInViewFilter是能解决Hibernate的懒加载问题,但是接踵而来的副作用就是:在执行持久化操作的时候,它把HQL语句都给缓存起来了,只有在返回到OpenSessionInViewFilter的closeSession方法flush掉session后才会真正执行(save、update、delete)的HQL语句。请问如何能避免这种情况的发生呢?

解决方案 »

  1.   

    利用 Spring AOP , 从切面获取到当前线程所对应(管理、使用)的 Session ,然后在切面中手动的 flash。
    至于如何在切面中获取当前线程的 Session 可以参照下 OpenSessionInViewFilter 中的代码实现。
      

  2.   

    OpenSessionInViewFilter没用过,学习学习
      

  3.   

    使用Spring的AOP管理事务,配置在指定的方法运行完成之后就提交事务,提交事务之后Session缓存中的对象将会持久化到数据库,可以非常容易的解决楼主的问题。<!-- 让Spring加载Hibernate的配置文件,并且产生sessionFactory对象 -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="configLocation">
    <value>classpath:hibernate.cfg.xml</value>
    </property>
    </bean>

    <!-- 指定事务管理器类,将sessionFactory注入,让该事务管理器具有打开和关闭事务的能力 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!-- 为事务管理器类指定匹配器,通过用name指定的匹配字符串进行对对应的方法进行打开和关闭事务 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
    <tx:method name="add*" propagation="REQUIRED"/>
    <tx:method name="delete*" propagation="REQUIRED"/>
    <tx:method name="modify*" propagation="REQUIRED"/>
    <tx:method name="deploy*" propagation="REQUIRED"/>
    <tx:method name="*" read-only="true"/>
    </tx:attributes>
    </tx:advice>

    <!-- 为事务管理器类指定进行匹配的范围,到指定的地方通过匹配器字符串进行筛选,对应上后为该方法打开和关闭事务 -->
    <aop:config>
    <aop:pointcut id="managerOperation" expression="execution(*com.lj.oalj.manager.*.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="managerOperation"/>
    </aop:config>上边的配置是将com.lj.oalj.manager包中的所有的类中的所有方法都作为Spring事务管理范围内,就是一旦调用了包中的方法,那么就会开启事务,方法结束后关闭事务。这和OpenSessionInViewFilter不冲突,它们两个都是用的时候Spring内部机制就是让OpenSessionInViewFilter来管理Session的开关,让Spring的AOP负责事务的开关。源代码中是这样做的。如果单独使用一个的话,那么就由这一个来同时管理Session和事务。希望对楼主有帮助。
      

  4.   

    我就实在不明白了.一个JSP请求过来,然后处理完所有事件,不正是你想要的?
    你说的副作用可以说细些么?没看出什么来.当然,如果流量大,一个请求可能内容较多,OOS不应该使用.它保存的数据库连接太久了.
    如果是事务处理 ,在Spring的源码里有关于这块的.AOP切下.会检查有没有配置了过滤器的.然后事务完了
    似乎会提交,(有些忘了).