为了解决hibernate的懒加载问题,我在项目中引入了Spring提供的OpenSessionInViewFilter(引入时已经重写了)。
引入OpenSessionInViewFilter是能解决Hibernate的懒加载问题,但是接踵而来的副作用就是:在执行持久化操作的时候,它把HQL语句都给缓存起来了,只有在返回到OpenSessionInViewFilter的closeSession方法flush掉session后才会真正执行(save、update、delete)的HQL语句。请问如何能避免这种情况的发生呢?
引入OpenSessionInViewFilter是能解决Hibernate的懒加载问题,但是接踵而来的副作用就是:在执行持久化操作的时候,它把HQL语句都给缓存起来了,只有在返回到OpenSessionInViewFilter的closeSession方法flush掉session后才会真正执行(save、update、delete)的HQL语句。请问如何能避免这种情况的发生呢?
至于如何在切面中获取当前线程的 Session 可以参照下 OpenSessionInViewFilter 中的代码实现。
<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和事务。希望对楼主有帮助。
你说的副作用可以说细些么?没看出什么来.当然,如果流量大,一个请求可能内容较多,OOS不应该使用.它保存的数据库连接太久了.
如果是事务处理 ,在Spring的源码里有关于这块的.AOP切下.会检查有没有配置了过滤器的.然后事务完了
似乎会提交,(有些忘了).