Hibernate的lazy属性总结
一对多情况下读取父类的子集合时,hibernate的lazy属性在其中的影响进行总结。(以下代码运行在jdk1.5,jboss eclipse ide 1.5,hibernate 3.1环境下)
假设有:父类 Person (含有Set类型属性Address),子类 Address(碰巧集合的名字和子类的名字都是Address,不要混淆了)Person.hbm.xml 主要片段:
< id name="idx" column="idx" type="long"> < generator class="identity"/> < /id> < property name="age" type="int" update="true" insert="true"column="age"/> < property name="name" type="java.lang.String" update="true"insert="true" column="name"/> < set name="address" table="address" lazy="true" cascade="none" sort="unsorted"> < key > < column name="personidx"/> < /key> < one-to-many class="com.abc.common.pojo.Address"/> < /set>
在session 的周期内,无论hibernate的lazy属性设为true or false, 不会有任何限制。访问父子数据的代码如下所示 :
//打开session session = HibernateUtil.currentSession(); PersonDAO dao = new PersonDAO(); Person person = null; person = (Person)dao.findByPrimaryKey(4); Set addressSet = person.getAddress(); Address[] addressAry = new Address[addressSet.size()]; Address address = null ; addressSet.toArray(addressAry); for(int i=0 ;i< addressAry.length;i++){ ................ } //session关闭 session.close(); if (session.isOpen()){ HibernateUtil.closeSession(); }
(2)在session的周期外,访问父子数据的代码如下所示 :
//打开session session = HibernateUtil.currentSession(); PersonDAO dao = new PersonDAO(); Person person = null; person = (Person)dao.findByPrimaryKey(4); session.close(); //session关闭之后才访问person的子集 Set addressSet = person.getAddress(); Address[] addressAry = new Address[addressSet.size()]; Address address = null ; addressSet.toArray(addressAry); for(int i=0 ;i< addressAry.length;i++){ ................ } if (session.isOpen()){ HibernateUtil.closeSession(); }
此时,上述代码的运行结果根据hibernate的lazy属性的设置的不同而不同
lazy=false
结果:可以访问得到Person和Address的数据
lazy= true
根据代码的写法有不同
(1)代码其他处不做任何处理,则抛出异常
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:
(2)如果做一些处理如下,将上述那段代码中的"留待后续处理"换成以下代码
Hibernate.initialize(person.getAddress()); 则可以访问得到Person和Address的数据