在获得session的时候使用sessionFactory.getCurrentSession()方法的时候,报错No Session found for current thread;
首先要理解:
1:getCurrentSession把session和当前线程关联起来,若session存在就不创建了直接调用,openSession只是重新开启一个session
2:getCurrentSession()获得的session会在事务关闭或者回滚时会自动关闭,而openSession获得的session必须手动关闭
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
具体报错的原因如下:
报错原因一:
这是因为在hibernate中他是通过sessionFactory调用CurrentSessionContext的currentSession()方法获取session的,当你的session为空时,他会自动调用sessionFactory.openSession()来创建一个session,而在集成的时候,session是交给spring来管理的,而spring也有一个自己的CurrentSessionContext实现,这个实现并不会自动为你创建session,所以就会报那个错误
报错原因二:
如果没有在spring配置TransationMnager的情况下,没调用sessionFactory.openSession()就直接调用sessionFactory.getCurrentSession(),就会报No Session found for current thread,因为当前没有session,而getCurrentSession()又不会为你创建
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
通过spring解决:
在spring中配置<tx:annotation-driven transaction-manager="transactionManager"/>
在spring配置了TransationMnager的情况下,有两种方式可以解决这个问题(此时spring会通过aop的方式为当前线程创建session,就可以正常调用getCurrentSession):
①通过@Transactional注解在方法上
②在spring添加事务属性和aop
<tx:advice id="advice">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="save*" propagation="REQUIRED" read-only="false" />
<tx:method name="*" isolation="READ_COMMITTED" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.smartBank.*.*.*(..))" id="pc"/>
<aop:advisor advice-ref="advice" pointcut-ref="pc"/>
</aop:config>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
通过hibernate解决:
在hibernate中配置<property name="current_session_context_class">thread</property>
这相当于不将session交给spring管理,原因是Hibernate在默认情况下会使用JTASessionContext来跟踪上下文的session,而Spring则提供了自己SpringSessionContext若没有配置,调用getCurrentSession()的效果完全依赖于spring的SpringSessionContext实现。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
建议:
①如果我们配置了TransactionManager,那么我们就不应该调用sessionFactory的openSession()来获得Sessioin,因为这样获得的session并没有被事务管理。
②当方法不需要事务支持的时候,sessionFactory.openSession()来获得Session对象。