spring声名式事务管理以及session生命周期
项目是spring+hibernate+struts框架,数据层BaseDaoImpl<T>中的 SessionFactory是通过注解方式,由spring来提供的实例。session 用的是 sessionFactory.getCurrentSession()来获取的,项目运行时报了“No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here ...”这个错误。
发生这个错误的根本原因是,声名式事务没有配置好。如果配置正确的话,断不会发生这个错误。
spring框架下,getCurrentSession()这个方法会判断当前的方法在不在事务当中,如果没有事务控制,那么将不会返回session对象,并报出异常。
这是一条华丽的分割线
-----------------------------------------------------------------------------
上述的这个session,调用完service层方法之后 就关闭了,如果在action方法中或者页面中访问实体的属性(实体中关联了其它实体,并设置了lazy加载),那么这个时候就会报错,类似这样的错failed to lazily initialize a collection of XXX: ......, no session or session was closed
这是由于session关闭了,获取不到。我们并不能因此就不使用lazy加载,所以要进一步配置:
用spring的OpenSessionInViewFilter把session的周期交给servlet filter来管理,这样可以让session存在于整个servlet request请求周期中,较之前的周期要长一些。配置方法如下:
在web.xml中添加
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilterOpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>