JAVA

 
 

常用链接

  • 我的随笔
  • 我的评论
  • 我的参与
  • 最新评论

留言簿(1)

  • 给我留言
  • 查看公开留言
  • 查看私人留言

随笔档案

  • 2006年7月 (1)

文章档案

  • 2006年11月 (3)
  • 2006年10月 (2)
  • 2006年9月 (4)
  • 2006年7月 (7)

搜索

  •  

最新评论

  • 1. re: Hibernate的关联关系映射
  • 评论内容较长,点击标题查看
  • --拉猪

Powered by: 博客园
模板提供:沪江博客
BlogJava | 首页 | 发新随笔 | 发新文章 | 联系 | 聚合 | 管理

我的评论

re: Hibernate的关联关系映射 拉猪 2006-11-10 14:52  
当出现 org.hibernate.LazyInitializationException:could not initialize proxy - the owing Session was closed 的错误时,是因为在集合类(collection)映射时,hibernate3默认的初始化方式是延迟初始化(laze initialize),即集合(不包括数组)是可以延迟初始化的,意思是仅仅当应用程序需要访问时,才载入他们的值。换句话说,如果有以下写法,则会抛出上述异常:

s = sessions.openSession();
User u = (User) s.find("from User u where u.name=?", userName, Hibernate.STRING).get(0);
Map permissions = u.getPermissions();
s.connection().commit();
s.close();
Integer accessLevel = (Integer) permissions.get("accounts"); // Error!

因为在这个Session被提交(commit)之前, permissions没有被初始化,那么这个集合将永远不能载入他的数据了。 解决方法是把读取集合数据的语句提到Session被提交之前。(然而,还有一种更先进的方法来解决这个问题。)
另外一种选择是不使用延迟初始化集合。既然延迟初始化可能引起上面这样错误,hibernate2默认是不使用延迟初始化的。但是, 为了效率的原因, hibernate3对集合(特别是实体集合)使用延迟初始化。
现在明白了,对于collection(实体类集合),hibernate2的默认不使用初始化方式,而hibernate3为了提高查询效率,默认采用了延迟初始化方式。
解决方式很简单:
在当前collection对象的hbm.xml配置文件中,加入laze="false"即可。如下:
<many-to-one name="..." class="..." column="..." not-null="false" lazy="false" />
由于在我当前项目中,DAOHibernate并没有采用sessions.openSession()和close()方式,所以只能采用修改其hbm.xml配置文件的方式来解决。