Java 弹簧石英的问题
我试图基于某个间隔时间调用该方法,下面是applicationContext.xml中的一些beanJava 弹簧石英的问题,java,spring,quartz-scheduler,Java,Spring,Quartz Scheduler,我试图基于某个间隔时间调用该方法,下面是applicationContext.xml中的一些bean <bean id="MngtTarget" class="com.management.engine.Implementation" abstract="false" lazy-init="true" autowire="default" dependency-check="default"> <bean id="jobDetail" class="org.
<bean id="MngtTarget"
class="com.management.engine.Implementation"
abstract="false" lazy-init="true" autowire="default" dependency-check="default">
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="MngtTarget" />
<property name="targetMethod" value="findItemByPIdEndDate"/>
</bean>
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="jobDetail" />
<!-- 10 seconds -->
<property name="startDelay" value="10000" />
<!-- repeat every 50 seconds -->
<property name="repeatInterval" value="20000" />
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="simpleTrigger" />
</list>
</property>
</bean>
<bean name="myJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.somecompany.worker.MyQuartzJob" />
<property name="jobDataAsMap">
<map>
<entry key="hibernateSessionFactory" value-ref="sessionFactory" />
<entry key="someDataDao" value-ref="someDataDao" />
</map>
</property>
</bean>
到目前为止,我已经花了很多时间在谷歌上搜索,我也尝试过这样修改我的方法:
public List<Long> I need findItemByPIdEndDate() throws Exception {
List<Long> list = null;
try{
Session session = sessionFactory.openSession();
Query query = session.getNamedQuery("endDateChecker");
list = query.list();
for(int i=0; i<list.size(); i++)
{
System.out.println(list.get(i));
}
System.out.println("Total " + list.size());
session.close();
}catch (HibernateException e){
throw new DataAccessException(e.getMessage());
}
return list;
}
对于第二个错误(“无法执行查询”),我不知道,我真的很想知道会话是什么样子
实际上,AFAIK,持久性上下文对Quartz作业不可用,因为没有任何东西可以为它们建立Hibernate会话(Quartz在servlet上下文之外运行,而opensession-In-view模式在这里不适用)。这就是为什么会出现第一个错误(“没有绑定到线程的hibernate会话”)
中介绍了一种解决方案。在这篇文章中,作者展示了如何使用SpringAOP代理连接hibernate拦截器,该拦截器允许您访问持久性上下文,并负责为您关闭和打开会话
虽然我自己没有测试它,但它应该可以工作。我也面临同样的“Hibernate异常:没有绑定到线程的Hibernate会话”异常
2012-01-13 13:16:15.005 DEBUG MyQuartzJob Caught an exception
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687)
at com.company.somemodule.dao.hibernate.AbstractHibernateDaoImpl.getSession(AbstractHibernateDaoImpl.java:107)
at com.company.somemodule.dao.hibernate.SomeDataDaoImpl.retrieveSomeData(SomeDataDaoImpl.java:264)
我通过下面的例子解决了这个问题
相关代码
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.SessionHolder;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import com.company.somemodule.dao.SomeDataDao;
import com.company.somemodule.SomeData;
public class MyQuartzJob extends QuartzJobBean implements Runnable {
private boolean existingTransaction;
private JobExecutionContext jobExecCtx;
private static Logger logger = LoggerFactory.getLogger(MyQuartzJob.class);
private SomeDataDao someDataDao; //set by Spring
private Session session;
private SessionFactory hibernateSessionFactory; //set by Spring
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException
this.jobExecCtx = ctx;
run();
}
private void handleHibernateTransactionIntricacies() {
session = SessionFactoryUtils.getSession(hibernateSessionFactory, true);
existingTransaction = SessionFactoryUtils.isSessionTransactional(session, hibernateSessionFactory);
if (existingTransaction) {
logger.debug("Found thread-bound Session for Quartz job");
} else {
TransactionSynchronizationManager.bindResource(hibernateSessionFactory, new SessionHolder(session));
}
}
private void releaseHibernateSessionConditionally() {
if (existingTransaction) {
logger.debug("Not closing pre-bound Hibernate Session after TransactionalQuartzTask");
} else {
TransactionSynchronizationManager.unbindResource(hibernateSessionFactory);
SessionFactoryUtils.releaseSession(session, hibernateSessionFactory);
}
}
@Override
public void run() {
// ..
// Do the required to avoid HibernateException: No Hibernate Session bound to thread
handleHibernateTransactionIntricacies();
// Do the transactional operations
try {
// Do DAO related operations ..
} finally {
releaseHibernateSessionConditionally();
}
}
public void setHibernateSessionFactory(SessionFactory hibernateSessionFactory) {
this.hibernateSessionFactory = hibernateSessionFactory;
}
public void setSomeDataDao(SomeDataDao someDataDao ) {
this.someDataDao = someDataDao ;
}
}
applicationContext.xml中的相关bean配置
<bean id="MngtTarget"
class="com.management.engine.Implementation"
abstract="false" lazy-init="true" autowire="default" dependency-check="default">
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="MngtTarget" />
<property name="targetMethod" value="findItemByPIdEndDate"/>
</bean>
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="jobDetail" />
<!-- 10 seconds -->
<property name="startDelay" value="10000" />
<!-- repeat every 50 seconds -->
<property name="repeatInterval" value="20000" />
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="simpleTrigger" />
</list>
</property>
</bean>
<bean name="myJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.somecompany.worker.MyQuartzJob" />
<property name="jobDataAsMap">
<map>
<entry key="hibernateSessionFactory" value-ref="sessionFactory" />
<entry key="someDataDao" value-ref="someDataDao" />
</map>
</property>
</bean>
有一个漏洞
还有解决办法。
使用hibernate配置会话。使用此类配置当前会话上下文类属性:
请添加您的Hibernate配置只需打印查询对象,然后查看您是否获得预期的查询
'endDateChecker'
您从哪里获得会话?我看不到您在任何地方将sessionFactory注入到对象中…谢谢m8,这不是解决方案,但它让我找到了一个,因此它符合正确答案的条件。我很高兴能帮上忙。然而,你能不能详细说明一下“这不是解决方案”,这样我就可以更新这个答案了?提前谢谢。
<bean name="myJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.somecompany.worker.MyQuartzJob" />
<property name="jobDataAsMap">
<map>
<entry key="hibernateSessionFactory" value-ref="sessionFactory" />
<entry key="someDataDao" value-ref="someDataDao" />
</map>
</property>
</bean>