关于在Spring托管Hibernate中使用定期任务产生No Hibernate Session bound to thread错误的解决

    最近的新项目想要做一件这样的事情:一个定期任务做一些业务逻辑与数据库操作。这个任务需要定时启动完成。

    我不想将定期任务新建一个后台java然后用bat进行处理,想直接将任务与web环境整合在一起。开始的时候自己编写了一个listener,在contextInitialized的地方 实例化一个timetask来做相应的事情。结果在task中想要进行hibernate调用的时候报错了,开始时候代码是这样的

web.xml中加入监听器

 

 

	<listener>
		<listener-class>
			com.taikang.imc.web.SmsTaskLoaderListener
		</listener-class>
	</listener>

 SmsTaskLoaderListener为监听器类

 

 

 

               //在contextInitialized中加入
                springContext = WebApplicationContextUtils
		.getWebApplicationContext(arg0.getServletContext());
		if(log.isDebugEnabled()){
			if(springContext!=null)
				log.debug("Spring ApplicationContext 初始化成功!");
			else
				log.debug("Spring ApplicationContext 初始化失败!");
		}
		ReceiveSmsTask rst =  new ReceiveSmsTask();
		rst.init(springContext);
		receiveScanner.scheduleAtFixedRate(rst, 2000, 6 * 1000);

 

 ReceiveSmsTask为任务类。

 后来运行中报错:No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here 大意是监听器中不存在Session,并且事务有配置问题。

查证了自己配置文件的事务部分,并无问题,整个WEB环境也能够正常运行,真是百思不得其解。

后来网上搜索,仔细查证,发现我的hibernate使用时候的文件中有这样的代码

 

 

public Session getSession() {
		return sessionFactory.getCurrentSession();
		// return sessionFactory.openSession();
	}
 

 

然后有人说:把其中的getCurrentSession改成openSession就可以使用,当没有事物启动的时候getCurrentSession是无法创建Session的。

 

参考:http://www.iteye.com/topic/87035

opensession是从sessionfactory得到一个新的session,所以可以使用,而getCurrentSession是从当前线程 中得到事务开始时创建transaction的那个session,而你的事务没有能正确的启动,所以并没有一个session绑定到当前线程,所以你也 得不到。

我的最终的解决办法是通过注解给我的service加上事务即可:@Transactional

于是给自己的

ReceiveSmsTask加上@Transactional 一路畅通

 

 

 

你可能感兴趣的:(Hibernate)