“could not initialize proxy -no Session”异常
出现这个问题主要是由于设置了懒加载,但在加载设置懒加载的关联内容时该session已经关闭。
最常见的就是向后台请求一个对象,拿到前台取出对象中的关联对象时,后台已经把session关闭。
最常见的解决办法有两种:
- 如果没有必要,可以取消懒加载。
- 可以使用spring提供的OpenSessionInViewFilter拦截器,延长session的周期,等到请求完毕再关闭session。
但有时候可能这两种方法都不能满足需求,就需要用其它办法了,那就是使用Hibernate.initialize(Object)方法,这个方法可以将传入的对象强制加载。
Student student = new Student();
Teacher teacher = student.getTeacher();
Hibernate.initialize(teacher); //进行强制加载
//可能由于某种原因需要清理或关闭session
System.out.println(teacher.getName()); //由于上面已经强制加载,即使session已经关闭,也可以输出关联对象的内容
注意:
-Hibernate.initialize()传入的对象是关联的对象,比如上面传入的是teacher而不是student
-Hibernate.initialize()方法不支持传入list、map等。
session的flush()、evict()、clear()方法
flush()方法的作用是清理缓存,强制将数据库与hibernate的缓存同步。它会向数据库发出sql语句,并执行这些sql语句,但不会向数据库提交。
commit()方法与这个方法类似,不同的是它多了一步,就是提交事务。在执行commit方法时,其实就是先调用flush方法,然后提交事务。
evict(Object)方法用于清除session中的指定对象的缓存。这个方法主要用于两个session同时要操作同一个对象的时候。
Student student = studentDao.getStudent();
student.setName("aa");
session.evict(student); //清除当前session中的student
newStudentDao.save(student); //hibernate不允许两个session同时使用一个对象,如果上面没有使用evict()方法,则会报错
clear()方法与evict()方法类似,只不过clear()方法会清楚session中的所有对象。