今天程序报了这样一个错: could not initialize proxy - no Session. 原因是在web.xml 中新增了
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/test/*</url-pattern>
</filter-mapping>
而在 web.xml 中的 是这样配置的, 而我在 struts2 的action 中调用了一个对象的关联对象属性, 导致了报这个错误
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate4.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
原理:
因为我们在hibernate里面load一个对象出来时,用到的是代理对象,也就是说当我们在执行load方法时并没有发sql语句,而是返回一个proxy对象。只有当们具体用到哪个get**方法时才会发sql语句,才会去数据库查。但是当我们把打开session,关闭session交给了srping去做时,当们load完之后我们的session就会被srping关闭,如果我们在jsp页面或者其它的地方再去用get方法取值时就会报这个错误。
解决方法:
方法一: 用到srping的filter(要加在strutsfilter有前面,因为它也有先后顺序,有先进先出的原则)
在我们的web.xml里面加上
这样做就是让opensession closesession全交给视图部分,最后视图部分用完了session再去关session就不会有上面的错误了
方法二:
直接不用懒加载,@ManyToOne(fetch=FetchType.LAZY) 改为 @ManyToOne(fetch=FetchType.EAGER)
但是有时候会报错, 就是没有对应的列, 但是数据库中明明是有的, 只能用一个笨方法, 就是在 service 中调用一下关联对象的属性
例如: A 中有一个关联对象 B, 那么在 sesrvice 中查询出 A 之后, 调用一下 a.getB().getName() 方法, 这样 B 就被加载出来了(name 为 B 的一个属性), 这样在 action 中再调用 a.getB() 方法就不会报错了