翻译的这篇文章包含了好几个知识点,虽然短了点儿,但是非常有用。
1.spring
2.hibernate
3.quartz--定时调度工具,spring已经做了封装,也可以单独使用。
4.OpenSessionInViewFilter--web框架下的一个filter,能够让web request使用单一的hibernate session。
有的j2ee项目在web.xml文件中添加了OpenSessionInViewFilter,其目的是给web request提供单一的hibernate session,但是它也只能给web request提供hibernate session。也就是说,如果有某一个hibernate请求不是经由web request发起的,而是由quartz这样的定时任务发起的,那么quartz怎么样才能得到hibernate session呢?
解决办法就是使用HibernateInterceptor。当quartz发起hibernate session请求时,HibernateInterceptor会提供一个hibernate session给它。
配置文件如下:
- <!-- Declaration of HibernateInterceptor -->
- <bean id="hibernateInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor">
- <property name="sessionFactory">
- <ref bean="sessionFactory"/>
- </property>
- </bean>
- <!-- Manager template -->
- <bean id="txProxyTemplate" abstract="true"
- class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
- <property name="transactionManager" ref="transactionManager"/>
- <property name="transactionAttributes">
- <props>
- <prop key="save*">PROPAGATION_REQUIRED</prop>
- <prop key="remove*">PROPAGATION_REQUIRED</prop>
- <prop key="update*">PROPAGATION_REQUIRED</prop>
- <prop key="create*">PROPAGATION_REQUIRED</prop>
- <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
- </props>
- </property>
- <property name="preInterceptors">
- <list>
- <ref bean="hibernateInterceptor"/>
- </list>
- </property>
- </bean>
- <!-- Sample Manager that encapsulates business logic -->
- <bean id="userManager" parent="txProxyTemplate">
- <property name="target">
- <bean class="com.acme.service.impl.UserManagerImpl" autowire="byName"/>
- </property>
- </bean>
其中,<!-- Declaration of HibernateInterceptor -->部分定义了HibernateInterceptor;
<!-- Manager template -->部分定义了模板,并且加入了HibernateInterceptor;
<!-- Sample Manager that encapsulates business logic -->部分定义业务逻辑中的bean,记住,一定让他使用模板。
译者言:
1.这样做使得非web request可以使用j2ee资源。
2.我的做法和上面有些差别,但是也成功了。 我的做法是:
我没有定义<!-- Declaration of HibernateInterceptor -->这一部分,只定义了模板,在添加bean的时候使用模板。
原文如下:
Using HibernateInterceptor to bind Hibernate Sessions for Quartz jobs in Spring
I use the OpenSessionInViewFilter to provide a single Hibernate Session for each request to my Spring webapplications. It works transparently and well, but only for web requests. So how do you provide a Hibernate Session to your background jobs (like Quartz scheduled jobs)?
I wire a HibernateInterceptor into my proxy template for all the managers in my application. With this configuration, when Quartz fires up a job and makes a call to the manager/service layer the HibernateInterceptor binds a Hibernate Session to the background thread. Beautiful.
It looks something like this:(代码同上)