HibernateInterceptor

不能用OpenSessionInView的情况,例如在quartz的job中需要保持hibernate的session

 

参考一下链接

 

http://forum.springsource.org/showthread.php?71337-OSIV-in-a-non-web-application

 

 

Our system is divided into two major "application" and "kernel" layers. Each layer hosts of a number of different services & components all deployed and wired together via spring. The kernel layer defines mechanism and the application layer defines policy. There is also a web-layer which calls into applications & kernel components to do configuration, monitoring..etc. At the moment, everything is running in-process.

To promote loose coupling, we generate ApplicationEvent(s) within the kernel layer which are processed asynchronously (on different thread pool threads) up in the application layer by whoever cares about them. The event handlers often call back down into kernel services which do use @Transactional but with no outer session available, I had LIE problems. At the same time, I did not want the application level event handlers to define an outer transaction scope and I also didn't want to put REQUIRES_NEW on all service methods in the kernel layer.

This is how the system is structured and this problem has nothing do with web interfaces or views. I wanted OSIV functionality inside the application event handlers. There are valid arguments against OSIV but I personally feel OSIV is necessary to get the full productivity benefit(s) of using an ORM in the first place.

First, I tried annotating the event handler with 
@Transactional(propagation=Propagation.NEVER) but that didn't work. The transaction manager still didn't bind a hibernate session for me. I'm not sure why but I didn't really look into it.

My solution also uses the HibernateInterceptor. I defined the interceptor and configured it with the same settings as the OSIV filter.


Code:
<bean id="hibernateSessionAdvice" class="org.springframework.orm.hibernate3.HibernateInterceptor">
	<property name="sessionFactory"><ref local="sessionFactory"/></property>
	 <property name="flushModeName" value="FLUSH_NEVER"/>
	 <property name="exceptionConversionEnabled" value="false"/>
</bean>
Then I created a marker annotation I can stick on any method where I want the hibernate interceptor to run.

Code:
package com.tvrc.as.support.spring;

public @interface HibernateSession {

}
I added an aop:config entry to tie the advice to any methods marked with the annotation.

Code:
 <aop:config>
   <aop:advisor pointcut="@annotation(com.tvrc.as.support.spring.HibernateSession)" advice-ref="hibernateSessionAdvice"/>
 </aop:config>
Finally, I just annotate event handlers where I'd like OSIV functionality.

Code:
@HibernateSession
public void onApplicationEvent(ApplicationEvent arg0) {
		//Call kernel services that define transactions
              //Session is available to avoid LIE
}
Spring is creating the application event listeners and wiring them all up so everything works well.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值