立时加载Hibernate动态代理的实体bean
立即加载Hibernate动态代理的实体bean
情况是这样的,struts2的action执行Service的方法get(Long id),它从数据库中获取满足id的记录并返回实体bean,其底层实现是Hibernate的Session的load()方法。要将得到的bean放入http session中,以后应用会用到。之后action重定向到另一个新的的action。问题是,即使在web.xml中配置了OpenSessionInViewFilter,以保证Hibernate session在view阶段不被关闭,那此时session也会关闭的,因为重定向到新的视图了嘛。因此,在新的视图中,用http session调用那个实体bean时会抛异常。为什么呢?
原因是,当Hibernate的实体lazy属性为true时,用load()和get()加载这些对象,Hibernate不会马上产生任何select语句,只是产生一个对象代理类实例,只有在Hibernate session没有关闭的情况下运行实例的getXxx()时才会执行select语句从数据库加载对象。此时session已经关闭了,自然抛异常了。怎么办?要立即加载动态代理的实体bean。
方法是,在将该bean放入session前,需要执行Hibernate.initialize(bean)方法,否则放入session的是该bean的动态代理,并没有加载实际数据,当session关闭后,也就得不到实际想要的数据了。Hibernate.initialize(bean)的作用是强行加载,即执行sql查询。