异常:No Hibernate Session bound to thread……

来源:互联网 发布:事业单位域名注册 编辑:程序博客网 时间:2024/06/04 22:47
No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here异常的处理
在基于注解的spring mvc+Hibernate项目中新增了一个spring自带的定时任务功能,访问数据库时出现如下异常:
[ERROR] 2017-01-20 21:27:00,205 [org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler] - Unexpected error occurred in scheduled task.
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:64)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:622)
at XXXXXX.dao.impl.AnalysisDaoImpl.getAllRoamData(AnalysisDaoImpl.java:195)
at XXXXXX.service.impl.AnalysisServiceImpl.getAllRoamData(AnalysisServiceImpl.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at net.bull.javamelody.MonitoringSpringInterceptor.invoke(MonitoringSpringInterceptor.java:73)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy33.getAllRoamData(Unknown Source)
at XXXXXX.task.MyTask.task(MyTask.java:135)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:64)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:53)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:207)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)

Spring中的定时任务配置文件:

<!-- task任务扫描注解 --><task:executor id="executor" pool-size="5" /><!-- 配置定时任务的线程池 -->        <task:scheduler id="scheduler" pool-size="10" />       <task:annotation-driven executor="executor" scheduler="scheduler" /><!-- 扫描位置 --><context:component-scan base-package="com.XXXXXX"></context:component-scan>

定时任务大略代码:
@Componentpublic class MyTask {@Autowiredprivate AnalysisService analysisService;   @Scheduled(cron="0/30 * * * * ? ")     public void task(){SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");Date start=new Date();System.out.println("=====================================================");System.out.println("执行数据统计任务>>>>>>>>");System.out.println("开始执行的时间为:"+sdf.format(start));String keywords="";int year=start.getYear()+1900;int month=start.getMonth();if(month==0){//如果是当年的第一个月,查询是上一年的最后一个月的数据year=year-1;month=11;}else{//查询是上个月的数据month=month-1;}String startTime=MyTask.getFirstDayOfMonth(year, month)+"00:00:00";String endTime=MyTask.getLastDayOfMonth(year, month)+"23:59:59";System.out.println("查询的时间段:"+startTime+"---"+endTime);List list = analysisService.getAllRoamData(keywords, startTime, endTime);Date end=new Date();System.out.println("结束执行的时间为:"+sdf.format(end));System.out.println("执行用时:"+(end.getTime()-start.getTime())+"ms");System.out.println("=====================================================");    }     public static String getFirstDayOfMonth(int year, int month) {              Calendar cal = Calendar.getInstance();              cal.set(Calendar.YEAR, year);              cal.set(Calendar.MONTH, month);           cal.set(Calendar.DAY_OF_MONTH,cal.getMinimum(Calendar.DATE));          return   new   SimpleDateFormat( "yyyy-MM-dd ").format(cal.getTime());       }           public static String getLastDayOfMonth(int year, int month) {              Calendar cal = Calendar.getInstance();              cal.set(Calendar.YEAR, year);              cal.set(Calendar.MONTH, month);              cal.set(Calendar.DAY_OF_MONTH,cal.getActualMaximum(Calendar.DATE));          return  new   SimpleDateFormat( "yyyy-MM-dd ").format(cal.getTime());       }   }

上面红色部分是访问数据库时就出错的地方,网上好多同样的错误,原因都是:因为没有设置事务,只要service对应的实现类上加上@Transactional就会正常。
这是一种解决方法。

我的解决方法:
在Dao的实现类中:把session的获取方法有 this.getSessionFactory().getCurrentSession()换成:this.getSession(),如下:
Query query = this.getSessionFactory().getCurrentSession().createSQLQuery(sql);
        Query query =this.getSession().createSQLQuery(sql);

现在有两点疑问:
1:为什么在service的实现类加上@Transactional就可以了,之前的代码未加为什么事务还是正常处理的?
2:this.getSessionFactory().getCurrentSession()this.getSession()有什么区别?

0 0
原创粉丝点击