在spring mvc+hibernate环境下出现了以下错误
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.ligang.modules.orm.hibernate.SimpleHibernateDao.getSession(SimpleHibernateDao.java:101)
at com.ligang.modules.orm.hibernate.SimpleHibernateDao.createCriteria(SimpleHibernateDao.java:322)
at com.ligang.modules.orm.hibernate.HibernateDao.findPage(HibernateDao.java:144)
网上普遍的解决方案如下:
opensession是从sessionfactory得到一个新的session,所以可以使用,而getCurrentSession是从当前线程 中得到事务开始时创建transaction的那个session,而你的事务没有能正确的启动,所以并没有一个session绑定到当前线程,所以你也 得不到。
大部分解决方案也是基于上面的思路:
- 简称sessionfactory配置是否正确
- transactionManager是否配置且已经生效。
- 在对应的service或者dao类或者方法上添加@Transactional注解。
我仔细检查了一下自己项目中的配置:
全部采用注解的方式,代码如下:
<!-- 使用annotation 自动注册bean,并保证@Required,@Autowired的属性被注入 -->
<context:component-scan base-package="com.myproject.web" />
<!-- 事务管理器配置,单数据源事务 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 使用annotation定义事务 -->
<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="true" />
目测上述配置没有问题,且在DAO层添加了@Transactional注解。
想到是不是spring自定义视图解析器时,hibernate 的session已经关闭的问题。
或许是因为session已经关闭才导致了上面获取不到?
检查一下web.xml文件,已经配置了org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
但是该过滤器定义的只是拦截*.do请求。而我的请求地址是:http://localhsot:8080/porject/index.shtml
也就是说我的这个请求并没有被OpenSessionInViewFilter过滤器拦截到。
增加一个拦截匹配:
<filter-mapping>
<filter-name>hibernateOpenSessionInViewFilter</filter-name>
<url-pattern>*.shtml</url-pattern>
</filter-mapping>
完成上述配置后,重启,测试通过。
可能别人碰到的问题和我的情况不一样,仅仅提供一种可以解决的方案。也有人说尽量不让使用OpenSessionInViewFilter,看个人选择吧。