当我运行SpringBootApplication和QuartzJobBean触发器时,我得到一个HibernateSystemException,表示Could not obtain transaction-synchronized Session for current thread
。当我在第一时间搜索Exception时,我发现了很多类似的问题(在SO上)但是没有一个提供的答案帮助了我。
我的ApplicationConfig看起来像这样。在这里,我设置了TransactionManager和Datasource等。
@SpringBootApplication(scanBasePackages = {"de.xxx.yyy"}, exclude = HibernateJpaAutoConfiguration.class)
@EnableTransactionManagement
public class ApplicationConfig extends SpringBootServletInitializer {
...
@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
return txManager;
}
@Bean
public LocalSessionFactoryBean sessionFactory() {
...
sessionFactory.setDataSource(dataSource());
sessionFactory.setHibernateProperties(hibernateProperties());
...
}
}
然后我有另一个Quartz配置 - QuartzSchedulerConfig。它配置触发器,详细信息和调度程序
@Configuration
@EnableTransactionManagement
public class QuartzSchedulerConfig {
@Autowired
DataSource dataSource;
@Autowired
ApplicationContext context;
@Autowired
QuartzTriggerProperties quartzTriggerProperties;
@Autowired
HibernateTransactionManager transactionManager;
@Bean
public SchedulerFactoryBean schedulerFactoryBean() throws ParseException, IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(context);
...
factory.setTransactionManager(transactionManager);
factory.setJobFactory(jobFactory);
...
factory.setTriggers(collectorTrigger());
return factory;
}
...
@Bean
public Trigger collectorTrigger() throws ParseException {
CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
factoryBean.setJobDetail(collectorJobDetail());
factoryBean.setName("collectorTrigger");
factoryBean.setCronExpression(quartzTriggerProperties.getCollectorTrigger())
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
@Bean
public JobDetail collectorJobDetail() {
JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
factoryBean.setJobClass(CollectorJob.class);
factoryBean.setDurability(true);
factoryBean.setApplicationContext(context);
factoryBean.setName("collectorJob");
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
...
}
现在,当我启动Application时,CollectorJob被执行,处理它的任务,最后当它试图将TransportVO
保存到数据库时,它失败并显示以下异常:
org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception:
org.springframework.orm.hibernate5.HibernateSystemException: Could not obtain transaction-synchronized Session for current thread; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread]
at org.quartz.core.JobRunShell.run(JobRunShell.java:213)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: org.springframework.orm.hibernate5.HibernateSystemException: Could not obtain transaction-synchronized Session for current thread; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:296)
at org.springframework.orm.hibernate5.HibernateExceptionTranslator.convertHibernateAccessException(HibernateExceptionTranslator.java:68)
at org.springframework.orm.hibernate5.HibernateExceptionTranslator.translateExceptionIfPossible(HibernateExceptionTranslator.java:49)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
at de.xxx.yyy.database.jobs.TransportDAO$$EnhancerBySpringCGLIB$$27fdef97.save(<generated>)
at de.xxx.yyy.business.services.collector.CollectorService.saveEventForTransporter(CollectorService.java:314)
at de.xxx.yyy.business.services.collector.CollectorService.downloadAndSaveArchiv(CollectorService.java:243)
at de.xxx.yyy.business.services.collector.CollectorService.saveArchivesToDownload(CollectorService.java:110)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:724)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
at de.xxx.yyy.business.services.collector.CollectorService$$EnhancerBySpringCGLIB$$cdf948ab.saveArchivesToDownload(<generated>)
at de.xxx.yyy.business.services.collector.CollectorJob.downloadArchives(CollectorJob.java:123)
at de.xxx.yyy.business.services.collector.CollectorJob.doDownloadForAllServer(CollectorJob.java:87)
at de.xxx.yyy.business.services.collector.CollectorJob.executeInternal(CollectorJob.java:73)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
... 1 more
Caused by: org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate5.SpringSessionContext.currentSession(SpringSessionContext.java:133)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:719)
at de.xxx.yyy.database.protocoll.QueryDSLSupport.getSession(QueryDSLSupport.java:35)
at de.xxx.yyy.database.jobs.TransportDAO.save(TransportDAO.java:65)
at de.xxx.yyy.database.jobs.TransportDAO$$FastClassBySpringCGLIB$$d4e14826.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 22 more
调用TransportDAO
的save-Method的Service-Method注释为@Transactional
,当客户使用该应用程序时,会话获取的TransactionManagement没有问题。所以我猜测我的QuartzScheduler在某种程度上是错误配置的。我需要改变什么才能使QuartzJobs工作?