在Hibernate 3.0 之后,引入了一个延迟加载的优化,可能在Session关闭的时候带来一定的问题。 当显示页面时提示Session is Closed的错误。
该问题主要可能由于在使用Hibernate时,开启了延迟加载特性。即在Hibernate 配置文件中加入了Lazy=true属性。一个简单的例子:
User 表 UserClass
userid username userclassid userclassid userclassname
1 hi 1 1 star
当使用hibernate进行持久对象映射,在配置文件中设置default-lazy="true",则在Hibernate在进行数据存取时,并不是直接生成真正的User对象(含有UserClass实例),而只是生成一个cglib代理对象。而如果在逻辑业务代码执行的过程中,加入了session.close()时,而如果在将来的页面渲染时候需要用到userclass.userclassname时,需要去取真正的User对象中的Userclass属性,而此时session已经被上面的代码关闭掉了,所以执行之后界面返回session is closed 错误。
解决方法:
1. 在执行业务逻辑的块中,删除session.close()这句,但是这同样会带来不关闭数据库连接所带来的巨大的并联消耗。如果是没有使用HibernateTemplate的情况下,只需要简单的刷新几次页面,在查询数据库连接的数目时,将会带来数量上的急剧上升。
2. 在Hibernate配置文件上,取消Hibernate的延迟加载的功能。如果是在配置文件只需 lazy = "false"
2.1 在class 上面设置时,只对普通的属性有效。无法对其中连接的子类起作用。
2.2 在单项属性上面设置,此处 property="userclass" lazy="false"
3. 如果是HSQL语句进行存取的话,如果是上述情况可以使用 from User as user left outer join fetch user.userClass, 明确的进行即刻加载,而不是生成
代理对象。