使用getCurrentSession()时获取“找不到当前线程的会话”exception

我使用的是Spring MVC 4.0.6和Hibernate 4.3.5。 我试图将值插入我的数据库表,但我收到此错误消息:

HTTP状态500 – 请求处理失败; 嵌套exception是org.hibernate.HibernateException:找不到当前线程的Session

目前我使用sessionFactory.getCurrentSession()来保存我的数据,但是如果我使用getSessionFactory().openSession(); 它完美地运作。 我听说我应该使用getCurrentSession而不是getSessionFactory().openSession(); 因为每次进行数据库查询时都会创建一个新会话。

你可以在下面看看我的代码并告诉我我做错了什么以及如何让sessionFactory.getCurrentSession()工作?

GradeServiceImpl:

 @Service @Transactional public class GradeServiceImpl implements GradeService { @Autowired private GradeDao gradeDao; @Override public void addGrade(Grade grade) { gradeDao.addGrade(grade); } } 

GradeDaoImpl

 @Repository @Transactional public class GradeDaoImpl implements GradeDao { @Autowired private SessionFactory sessionFactory; public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override public void addGrade(Grade grade) { sessionFactory.getCurrentSession().save(grade); } } 

servlet的context.xml中

                        <!--  classpath:hibernate.cfg.xml  -->    org.hibernate.dialect.MySQLDialect true create true        

在web.xml

     contextConfigLocation /WEB-INF/spring/root-context.xml    org.springframework.web.context.ContextLoaderListener    appServlet org.springframework.web.servlet.DispatcherServlet  contextConfigLocation /WEB-INF/spring/appServlet/servlet-context.xml  1   appServlet /   

更新 – 堆栈跟踪

例外

 org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.HibernateException: No Session found for current thread org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973) org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863) javax.servlet.http.HttpServlet.service(HttpServlet.java:647) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 

根本原因

 org.hibernate.HibernateException: No Session found for current thread org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:106) org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014) com.spring.org.dao.GradeDaoImpl.addGrade(GradeDaoImpl.java:33) com.spring.org.service.GradeServiceImpl.addGrade(GradeServiceImpl.java:25) com.spring.org.GradeController.saveGrade(GradeController.java:32) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) java.lang.reflect.Method.invoke(Unknown Source) org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689) org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863) javax.servlet.http.HttpServlet.service(HttpServlet.java:647) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 

在你的hibernate属性中,添加这一行。

  thread 

所以你的hibernateProperties看起来像这样,

    org.hibernate.dialect.MySQLDialect true create //add this thread true  

你需要开一个交易。 所以这样做。

 public void addGrade(Grade grade) { Session session = sessionFactory.getCurrentSession() Transaction tx = null; try{ tx = session.beginTransaction(); session.save(grade); tx.commit(); }catch (HibernateException e) { if (tx!=null) tx.rollback(); e.printStackTrace(); }finally { session.close(); } } 

}

我有同样的问题。

我使用的是基于注释的配置,我已经配置了sessionfactory,datasource和事务管理器。 但是我没有在AppConfig类中给出@EnableTransactionManagement注释。

添加事务注释后,代码如下所示。

 @Configuration @ComponentScan("com.bmp.*") @EnableWebMvc @PropertySource("classpath:${env}.properties") @EnableTransactionManagement public class AppConfig { ----- } 

上面的注释解决了我的问题。

如果这可以解决您的问题,请进行投票,以便对其他人有所帮助。

您应该删除DAO实现上的@Transactional注释。 而是在您的Service方法中;

 @Override @Transactional public void addGrade(Grade grade) { gradeDao.addGrade(grade); } 

对于所有数据库操作,只有服务实现需要@Transactional。

这是最新发生的事情:

当你使用sessionFactory.getCurrentSession()而不是sessionFactory.openSession() hibernate将寻找绑定到应用程序上下文线程的会话实例(换句话说,单个会话实例将由hibernate管理,并在会话中调用getCurrentSession()时返回工厂)。

现在要配置绑定到应用程序上下文线程的会话,您必须在hibernate属性中指定它。 你可以通过向hibernateProperties添加以下属性来实现:

 thread 

之所以sessionFactory.openSession()没有hibernate属性的情况下正常工作是因为hibernate不会查找绑定到应用程序上下文的会话,每次在sessionFactory上调用openSession()时都需要创建一个新的会话实例。

希望这对你有所帮助。

正如Narmer所说,你将所有的数据库配置放在servlet-context.xml ,它应该放在root-context.xml 。 但问题的真正原因(或其症状)是您不使用事务代理,因为它可以在stacktrace中看到: GradeController.saveGrade直接调用GradeServiceImpl.addGrade ,而GradeServiceImpl.addGrade又直接调用GradeDaoImpl.addGrade

通常,您应该仅将@Transactional注释放在服务层中,而不是放在dao层中(只有一个事务层)。 并且您应该validation您是否从控制器自动assembly服务

 @Autowired private GradeService gradeService; 

请尝试仅使用一个事务层,并说出stacktrace是否显示事务代理使用情况。

编辑:

您的配置中还有另一个问题:当spring需要正确处理@Transactional注释时,您没有标记。

尝试使用旧版本的弹簧…我使用弹簧3.2.8.RELEASE与hibernate 4.2.11.Final …