最近在进行框架整合,no session问题频繁出现,所以今天写下本文,说一下我遇见的问题,希望可以对广大同行有一点帮助。
在整合spring和hibernate时出现了一个很大的问题,就是在测试类中,频繁出现一下问题:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
在查阅了一些资料后,知道了出现这个问题的原因主要在于使用了以下方法:
Emp emp=this.getHibernateTemplate().load(Emp.class,id);
这个通过继承HibernateDaoSupport后调用的方法有一个特性,那就是在调用该方法时,由于懒加载(lazy)的原因,程序并没有发送查询语句,也就是并没有与数据库进行交互,所以并没有值,而该方法的特性是调用方法后便关闭session,而当系统发出查询时,session已经关闭了,所以出现了no session的异常。
对于该问题的解决方案,可以使用过滤器opensession的方法,以下为代码段:
在web.xml文件中配置:
<!--
放置session closed异常出现。
spring的session过滤器
-->
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这样可以在与页面交互式把session延长至web端,避免了session过早关闭的问题。
其实不用过于纠结测试类中出现问题,在实际操作中可以解决该问题就可以了,因为·在测试类中我们很难在单独调用该方法时延长session。
如果一定要解决测试类中的该问题,可以尝试用其他方法延长session,在该session中调用load方法即可,以下为代码:
@org.junit.Test
public void saveB(){
Emp emp=new Emp();
emp.setEmpNo(1008);
emp.seteName("ff");
emp.setJob("老五");
emp.setHiredate(DateConverterUtils.String2Date("2017-10-11"));
emp.setSal(2000);
Emp mgr=this.empBiz.loadById(1001);
System.out.println(mgr);
emp.setMgr(mgr);
Dept d=new Dept();
d.setDname("sasa");
d.setDeptNO(2);
d.setLoc("sas");
Dept dept=this.deptBiz.find(d);
emp.setDept(d);
// Dept dept=this.deptBiz.loadById(1);
// emp.setDept(dept);
this.empBiz.save(emp);
}