请大神帮帮忙,困扰我一周了.No Hibernate Session bound to thread, and configuration does not..

terrychen98 2014-08-20 12:21:37
自建 springmvc+hibernate 项目

该死的报错: 请大神帮忙!
No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

开发工具:
myEclipse 10.0
tomcat 6.0

测试service可以得到结果,使用session如下代码,可以正常从数据库增删改查.
Session session = sessionFactory.getCurrentSession();  //方法一
Session session = sessionFactory.openSession(); //方法二
session.close();

public static void main(String[] args) {
ApplicationContext con = new ClassPathXmlApplicationContext("applicationContext.xml");
StudentService studentService = (StudentService) con.getBean("studentServiceImpl");
List<ZtStudentLog> list = studentService.getTotalStudent();
for (ZtStudentLog z : list) {
System.out.println(z.getUsername()+" "+z.getAge()+" "+z.getId()+" "+z.getSex());
}
}
结果如下:
Hibernate: select this_.ID as ID0_0_, this_.AGE as AGE0_0_, this_.SEX as SEX0_0_, this_.USERNAME as USERNAME0_0_ from ZT_STUDENT_LOG this_
王1 66 1 男
王2 55 2 女
王4 33 4 女
码子 13 5 女
码2 45 3 女

但是在controller层调用的时候就会出问题,只能用方法二进行查询,增删改会产生相应的sql语句但不能对数据库进行操作,方法一就直接报错 No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here 心都碎了 急死了,下面直接上代码,求大神们帮我看看.

web.xml部分代码:

<!-- 上下文配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- springmvc配置 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
applicationContext.xml部分代码:

<context:component-scan base-package="com.pb" />
<!-- 读取jdbc.properties文件信息,方便更改数据库 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- hibernate注释写法,不需要写*.hbm.xml了. -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${jdbc.hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${jdbc.hibernate.format_sql}</prop>
</props>
</property>
<property name="packagesToScan" value="com.pb.model." />
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" propagation="REQUIRED" read-only="true"/>
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:config >
<aop:pointcut expression="execution(public * com.pb.service.impl.*.*(..))" id="pointCut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>
</beans>
springmvc-servlet.xml部分代码:

<!-- 默认的注解映射的支持 -->
<!-- <mvc:annotation-driven/> -->
<!-- 自动扫描的包名,对定义包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能 -->
<context:component-scan base-package="com.pb" />
<!-- 视图解释类 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" /> <!--可为空,方便实现自已的依据扩展名来选择视图解释类的逻辑 -->
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<!-- 去掉了也能用JSTL.去掉了能用是因为JSTL:你加载了JSTL的标签架包。 -->
</bean>
</beans>
StudentDaoImpl.java部分代码:

@Repository
public class StudentDaoImpl implements StudentDao {
@Autowired
private SessionFactory sessionFactory;
@SuppressWarnings("unchecked")
@Override
public List<ZtStudentLog> getTotalStudent() {
Session session = sessionFactory.getCurrentSession(); //用这个会报错,线程中不存在session
// Session session = sessionFactory.openSession(); //用opensessoin不会报错,但不对数据库进行操作
List<ZtStudentLog> list = session.createCriteria(ZtStudentLog.class).list();
// session.close();
return list;
}
@Override
public void addStudent(ZtStudentLog ztStudentLog) {
// Session session = sessionFactory.getCurrentSession();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.saveOrUpdate(ztStudentLog);
session.flush();
session.close();
}
}
StudentServiceImpl.java部分代码:

@Service()
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentDao studentDao;
@Override
public List<ZtStudentLog> getTotalStudent() {
return studentDao.getTotalStudent();
}
@Override
public void addStudent(ZtStudentLog ztStudentLog) {
studentDao.addStudent(ztStudentLog);
}
}
testController.java部分代码:

@Controller
@RequestMapping("/test")
public class testController {
@Autowired
private StudentService studentService;
private List<ZtStudentLog> studentList;
public List<ZtStudentLog> getStudentList() {
return studentList;
}
public void setStudentList(List<ZtStudentLog> studentList) {
this.studentList = studentList;
}
@RequestMapping(value="/test0",method=RequestMethod.GET)
public String gettest0 (HttpServletRequest request) {
this.studentList = studentService.getTotalStudent();
request.setAttribute("studentList", studentList);
return "student_list";
}
@RequestMapping(value="/add0",method=RequestMethod.GET)
public String add0 () {
System.out.println("get进入======");
return "student_add";
}
}
student_list.jsp部分代码:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'studnet_list.jsp' starting page</title>
</head>

<body>
<center>
${msg }
<table border="1">
<tr>
<td>编号</td>
<td>姓名</td>
<td>年龄</td>
<td>性别</td>
</tr>
<c:forEach var="student" items="${studentList}" varStatus="status">
<tr>
<td>${student.id }</td>
<td>${student.username }</td>
<td>${student.age }</td>
<td>${student.sex }</td>
</tr>
</c:forEach>
</table>
<a href="add0">添加信息</a>
</center>
</body>
</html>
报错详情:
2014-8-20 12:17:06 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet springmvc threw 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:622)
at com.pb.dao.impl.StudentDaoImpl.getTotalStudent(StudentDaoImpl.java:21)
at com.pb.service.impl.StudentServiceImpl.getTotalStudent(StudentServiceImpl.java:20)
at com.pb.controller.testController.gettest0(testController.java:37)
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.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:228)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:634)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445)
at java.lang.Thread.run(Thread.java:619)
...全文
16387 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
asd65285 2015-05-05
  • 打赏
  • 举报
回复
引用 12 楼 fangmingshijie 的回复:
<tx:annotation-driven transaction-manager="transactionManager"/>配置到spring-servlet.xml里。
哈哈,我来解释原理 传送门:http://blog.csdn.net/z69183787/article/details/37819831
csdn_java_coder 2015-01-14
  • 打赏
  • 举报
回复
引用 13 楼 terrychen98 的回复:
[quote=引用 12 楼 fangmingshijie 的回复:] <tx:annotation-driven transaction-manager="transactionManager"/>配置到spring-servlet.xml里。
万分感谢 fangmingshijie 我把这句整spring-servlet.xml里了,就ok了,困扰我一周的问题终于解决了,你是我的神啊,[/quote] 晕倒 ! 有没有原理说法
  • 打赏
  • 举报
回复
你要在 <property name="hibernateProperties">里配置一个<prop name="current_session_context_class">thread</prop> 你调用getSession()、getCurrentSession()时,都会打开session,而且会绑定到你当前线程,你又配置了事务,当事务被commit后,getCurrentSession()返回的session自动关闭了,而getSession()的session还在打开,所以当你再次调用的时候,就报哪个错误了。
terrychen98 2014-08-20
  • 打赏
  • 举报
回复
引用 3 楼 zy353003874 的回复:
出现这个问题主要是由于你调用了getCurrentSession()方法,所以你需要在配置文件中把这个绑定到当前线程中取,其次如果绑定了仍然出现这个错误,那么就是你整合的问题了,在spring3整合hibernate4的版本的时候,就会出现这个问题,具体你看看spring的开发文档
请问下 具体怎么在配置文件中把这个绑定到当前线程,我不太懂 我用的hibernate3这个版本 代码基本都在上面了 就是不对 头疼!!!
zy_think123 2014-08-20
  • 打赏
  • 举报
回复
出现这个问题主要是由于你调用了getCurrentSession()方法,所以你需要在配置文件中把这个绑定到当前线程中取,其次如果绑定了仍然出现这个错误,那么就是你整合的问题了,在spring3整合hibernate4的版本的时候,就会出现这个问题,具体你看看spring的开发文档
terrychen98 2014-08-20
  • 打赏
  • 举报
回复
可以具体点吗,我是新手,不太懂,之前使用注解来做的,
<tx:annotation-driven transaction-manager="transactionManager" />
还是不行,后来换的申明式事务,但是我在service层直接跑数据是ok的,那是不是跟aop没关系啊?
小灯光环 2014-08-20
  • 打赏
  • 举报
回复
AOP事务切面配置的有问题,检查一下。
terrychen98 2014-08-20
  • 打赏
  • 举报
回复
引用 12 楼 fangmingshijie 的回复:
<tx:annotation-driven transaction-manager="transactionManager"/>配置到spring-servlet.xml里。
万分感谢 fangmingshijie 我把这句整spring-servlet.xml里了,就ok了,困扰我一周的问题终于解决了,你是我的神啊,
  • 打赏
  • 举报
回复
<tx:annotation-driven transaction-manager="transactionManager"/>配置到spring-servlet.xml里。
terrychen98 2014-08-20
  • 打赏
  • 举报
回复
引用 9 楼 hungge 的回复:
没仔细看完,不过问题应该处在事物管理上面,看了你的aop中设置事物是加载service中的,那么你在control中调用服务器的操作 就会有问题了,hibernate的session在事物结束时就关闭了。 两种方式修改:1.把事物加在controller层,不过好像不合适。2.所有的数据库操作都放service层,这样就没问题了。 或者兼容一下,某些control中的方法加事物。 我一般使用spring的 @transcational 来控制事物。 另外还有个需要注意的。 hibernate的load方法,使用不合理也会出这样的问题。比如你load了一个延迟加载的对象,但是事物关闭后,这个对象中再次使用getter方法时,就会报错误了
我调整了代码用注解事务
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
serviceimpl层
@Service()
@Transactional
public class StudentServiceImpl implements StudentService {
这个在service层连接数据库ok,但在controller层调用又报这个错了: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
terrychen98 2014-08-20
  • 打赏
  • 举报
回复
引用 7 楼 zy353003874 的回复:
如果仅仅只是hibernate的话,那么配置thread就可以了,但是如果是把hibernate交给spring的话,那么就不能配置thread,因为找不到,这个时候需要配置:
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
如果还是出现这个问题的话,那么就是版本的问题了
[/quote] 我使用的hibernate3+spring3.05 用的这个代码片段
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>
还是报错 No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here我要疯了,代码咋看咋对,就是从controller层调用就报错...
csdn_java_coder 2014-08-20
  • 打赏
  • 举报
回复
没仔细看完,不过问题应该处在事物管理上面,看了你的aop中设置事物是加载service中的,那么你在control中调用服务器的操作 就会有问题了,hibernate的session在事物结束时就关闭了。 两种方式修改:1.把事物加在controller层,不过好像不合适。2.所有的数据库操作都放service层,这样就没问题了。 或者兼容一下,某些control中的方法加事物。 我一般使用spring的 @transcational 来控制事物。 另外还有个需要注意的。 hibernate的load方法,使用不合理也会出这样的问题。比如你load了一个延迟加载的对象,但是事物关闭后,这个对象中再次使用getter方法时,就会报错误了
terrychen98 2014-08-20
  • 打赏
  • 举报
回复
引用 5 楼 fangmingshijie 的回复:
你要在 <property name="hibernateProperties">里配置一个<prop name="current_session_context_class">thread</prop> 你调用getSession()、getCurrentSession()时,都会打开session,而且会绑定到你当前线程,你又配置了事务,当事务被commit后,getCurrentSession()返回的session自动关闭了,而getSession()的session还在打开,所以当你再次调用的时候,就报哪个错误了。
我用了这个方法,但还是不行第一次使用:hibernate.current_session_context_class
<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">${jdbc.hibernate.dialect}</prop>
				<prop key="hibernate.show_sql">${jdbc.hibernate.show_sql}</prop>
				<prop key="hibernate.format_sql">${jdbc.hibernate.format_sql}</prop>
				<prop key="hibernate.current_session_context_class">thread</prop>
			</props>
		</property>
直接就跑不动了,报错 createCriteria is not valid without active transaction 第二次我用: current_session_context_class
<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">${jdbc.hibernate.dialect}</prop>
				<prop key="hibernate.show_sql">${jdbc.hibernate.show_sql}</prop>
				<prop key="hibernate.format_sql">${jdbc.hibernate.format_sql}</prop>
				<prop key="current_session_context_class">thread</prop>
			</props>
		</property>
这个在service层连接数据库ok,但在controller层调用又报这个错了: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here大神,请帮帮忙!
zy_think123 2014-08-20
  • 打赏
  • 举报
回复
引用 5 楼 fangmingshijie 的回复:
你要在 <property name="hibernateProperties">里配置一个<prop name="current_session_context_class">thread</prop> 你调用getSession()、getCurrentSession()时,都会打开session,而且会绑定到你当前线程,你又配置了事务,当事务被commit后,getCurrentSession()返回的session自动关闭了,而getSession()的session还在打开,所以当你再次调用的时候,就报哪个错误了。
引用 4 楼 terrychen98 的回复:
[quote=引用 3 楼 zy353003874 的回复:] 出现这个问题主要是由于你调用了getCurrentSession()方法,所以你需要在配置文件中把这个绑定到当前线程中取,其次如果绑定了仍然出现这个错误,那么就是你整合的问题了,在spring3整合hibernate4的版本的时候,就会出现这个问题,具体你看看spring的开发文档
请问下 具体怎么在配置文件中把这个绑定到当前线程,我不太懂 我用的hibernate3这个版本 代码基本都在上面了 就是不对 头疼!!![/quote] 如果仅仅只是hibernate的话,那么配置thread就可以了,但是如果是把hibernate交给spring的话,那么就不能配置thread,因为找不到,这个时候需要配置:
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
如果还是出现这个问题的话,那么就是版本的问题了
  • 打赏
  • 举报
回复
你在private SessionFactory;下面再加上SessionFactory的get和Set方法!!!主要是set方法; 还有sessionFactory.getCurrentSession()这个方法是会自动关闭Session等功能的,不需要再手动关闭了 。。。 所以也不用Session.close()了

81,095

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧