hibernate在使用getCurrentSession时提示no session found for current thread

Posted y酒味i

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate在使用getCurrentSession时提示no session found for current thread相关的知识,希望对你有一定的参考价值。

大致错误片段

org.hibernate.HibernateException: No Session found for current thread
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)

 

 

大致问题:hibernate在处理sessoin

  SessionFactory的getCurrentSession并不能保证在没有当前Session的情况下会自动创建一个新的,这取决于CurrentSessionContext的实现,SessionFactory将调用CurrentSessionContext的currentSession()方法来获得Session。

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

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

  Hibernate在默认情况下会使用JTASessionContext,Spring提供了自己SpringSessionContext,因此我们不用配置current_session_context_class,当Hibernate与Spring集成时,将使用该SessionContext,故此时调用getCurrentSession()的效果完全依赖于SpringSessionContext的实现。

  在没有Spring的情况下使用Hibernate,如果没有在hibernate.cfg.xml中配置current_session_context_class,有没有JTA的话,那么程序将抛出"No CurrentSessionContext configured!"异常。此时的解决办法是在hibernate.cfg.xml中将current_session_context_class配置成thread。

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

 

解决问题:

1.首先检查web.xml 的问题

是否配置了org.springframework.orm.hibernate4.support.OpenSessionInViewFilte

  <filter>
    <filter-name>openSessionInVieFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>openSessionInVieFilter</filter-name>
    <url-pattern>/web/*</url-pattern>
  </filter-mapping>

 

OpenSessionInViewFilte的作用:Spring为我们解决Hibernate的Session的关闭与开启问题。 

 

2.检查spring事物配置路径是否正确

(以下列出一个案例)

    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <!-- 声明式事务管理begin -->
    <aop:config>         
        <aop:advisor pointcut="execution(* com.*.*.service.impl..*ServiceImpl.*(..))" advice-ref="txAdvice"/>
    </aop:config>
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="load*" read-only="true"/>
            <tx:method name="query*" read-only="true"/>
            <tx:method name="*" rollback-for="Exception"/>
        </tx:attributes>
    </tx:advice>
    <!-- 声明式事务管理end -->

 

 

3.如上面两个都正确的情况下考虑在sessionfactory中添加hibernate的属性,自动创建session

sessionFactory里面加上   

 <prop key="current_session_context_class">thread</prop>    

 

以上是关于hibernate在使用getCurrentSession时提示no session found for current thread的主要内容,如果未能解决你的问题,请参考以下文章

getCurrentSession() 与 openSession()

为啥 Spring 在使用 Hibernate 3 时推迟关闭 Hibernate 会话

在JavaEE中使用Hibernate框架

搭建hibernate环境

在Spring中使用Hibernate 4

ReactiveCrudRepository 在春季使用 Hibernate