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配置文件的方式来解决。