Could not obtain transaction-synchronized Session for current thread

Posted 哆啦任意门

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Could not obtain transaction-synchronized Session for current thread相关的知识,希望对你有一定的参考价值。

今天运行程序时  报了 如下的错误。

Could not obtain transaction-synchronized Session for current thread 

在Spring中使用Hibernate,如果我们配置了TransactionManager,那么我们就不应该调用SessionFactory的openSession()来获得Sessioin,因为这样获得的Session并没有被事务管理。我们应该使用getCurrentSession()

Spring 修改

在Spring中,如果我们在没有配置TransactionManager并且没有事先调用SessionFactory.openSession()的情况直接调用getCurrentSession(),那么程序将抛出“No Session found for current thread”异常。如果配置了TranactionManager并且通过@Transactional或者声明的方式配置的事务边界,那么Spring会在开始事务之前通过AOP的方式为当前线程创建Session,此时调用getCurrentSession()将得到正确结果。

可以由上面的看到首先在Spring 和Hibernate 整合时 ,如果我们没有配置TranscationManager,但是直接调用了getCurrentSession(),那么就出现了这个错误,所以我们现在首先要将TranscationManager 加入进来。

解决办法:

1. 在Spring中加入事务 即使这个只是个查询的事务,不过我们可以设置此为一个ReadOnly 事务

1) 将事务的标签加入对应的方法中

 

1     @Transactional(readOnly = true)
2     public int findBookPriceByIsbn(String isbn) {
3         String hql = "SELECT b.price FROM Book b WHERE b.isbn = ?";
4         Query<Integer> query =  getSession().createQuery(hql).setParameter(0, isbn);
5         return query.uniqueResult();
6     }

 

2)在xml中配置事务

1     <bean id="transactionManager"
2         class="org.springframework.orm.hibernate5.HibernateTransactionManager">
3         <property name="sessionFactory" ref="localSessionFactoryBean"></property>
4     </bean>
5 
6     <tx:annotation-driven transaction-manager="transactionManager" />

 

Hibernate中修改:

其实我们也可以在Hibernate 中进行修改 , 当我们不需要Spring的时候

然而,产生以上异常的原因在于Spring提供了自己的CurrentSessionContext实现,如果我们不打算使用Spring,而是自己直接从hibernate.cfg.xml创建SessionFactory,并且为在hibernate.cfg.xml
中设置current_session_context_class为thread,也即使用了ThreadLocalSessionContext,那么我们在调用getCurrentSession()时,如果当前线程没有Session存在,则会创建一个绑定到当前线程。

 

我们可以看到 当我们不使用Spring的时候 其实也会出现这个错误,归根结底在于有没有开这个session

解决方案:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6     <session-factory>
 7         <property name="hibernate.dialect">org.hibernate.dialect.mysql5InnoDBDialect</property>
 8         <property name="hibernate.show_sql">true</property>
 9         <property name="hibernate.format_sql">true</property>
10         <property name="hibernate.hbm2ddl.auto">update</property>
       //添加新的属性 11 <property name="current_session_context_class">thread</property> 12 </session-factory> 13 </hibernate-configuration>

web.xml解决方案:

在项目中,利用SessionFactory.getCurrentSession()方法获取hibernate的会话,当在一个controller方法中多次使用访问数据库,会报出错误:Could not obtain transaction-synchronized Session for current thread
在这里应该用一下spring中的OpenSessionInViewFilter,否则,需要每次使用完成后关闭session,下一次使用才不会报错,但是又涉及到一个lazy loading的问题,关闭session之后就无法懒加载,所以使用OpenSessionInViewFilter是一个两全的选择

1  <filter>
2        <filter-name>SpringOpenSessionInViewFilter</filter-name>
3        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
4      </filter>
5   <filter-mapping>
6     <filter-name>SpringOpenSessionInViewFilter</filter-name>
7     <url-pattern>/*</url-pattern>
8   </filter-mapping>

 参考资料:

1.SpringMVC4+Hibernate4运行报错Could not obtain transaction-synchronized Session for current thread

2. Hibernate4 No Session found for current thread原因

3. spring+hibernate Could not obtain transaction-synchronized Session for current thread                     

以上是关于Could not obtain transaction-synchronized Session for current thread的主要内容,如果未能解决你的问题,请参考以下文章

Could not obtain transaction-synchronized Session for current thread

Could not obtain transaction-synchronized Session for current thread

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thre

Could not obtain transaction-synchronized Session for current thread

Could not obtain connection metadata

Could not obtain connection to query metadata : Public Key Retrieval is not allowed