Hibernate之lazy屬性介紹
本文主要針對一對多情況下讀取父類的子集合時(shí),hibernate 的lazy屬性在其中的影響進(jìn)行總結(jié)。(以下代碼運(yùn)行在jdk1.5,jboss eclipse ide 1.5,hibernate 3.1環(huán)境下)
假設(shè)有:父類 Person? (含有Set類型屬性Address),
??????????????? 子類 Address(碰巧集合的名字和子類的名字都是Address,不要混淆了)
?????????????? ? Person.hbm.xml? 主要片段:
??????? <id
??????????? name="idx"
??????????? column="idx"
??????????? type="long"
??????? >
??????????? <generator class="identity">
??????????? </generator>
??????? </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>
????(1)在session 的周期內(nèi),無論lazy 設(shè)為true or false,?不會有任何限制。訪問父子數(shù)據(jù)的代碼如下所示?:???????
??? ?//打開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關(guān)閉
??? session.close();
?????if (session.isOpen()){
??????? ? HibernateUtil.closeSession();
??? }
(2)在session的周期外,訪問父子數(shù)據(jù)的代碼如下所示?:
???? //打開session??
???? session = HibernateUtil.currentSession();
?????PersonDAO dao = new PersonDAO();
???? Person person = null;
???? person = (Person)dao.findByPrimaryKey(4);
?????/**********************
????? *留待后續(xù)處理
????? *********************/
???? session.close();
????
???? //session關(guān)閉之后才訪問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();
??? }
?? 此時(shí),上述代碼的運(yùn)行結(jié)果根據(jù)lazy的設(shè)置的不同而不同
lazy=false
???結(jié)果:可以訪問得到Person和Address的數(shù)據(jù)
lazy= true
??? 根據(jù)代碼的寫法有不同
??? (1)代碼其他處不做任何處理,則拋出異常
???????? org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:?
???????? 。。。。。。
??? (2)如果做一些處理如下,將上述那段代碼中的"留待后續(xù)處理"換成以下代碼
?????????? Hibernate.initialize(person.getAddress());? 則可以訪問得到Person和Address的數(shù)據(jù)
???????? 實(shí)際編寫時(shí),不會象上述這樣的寫法,即將
???????? Hibernate.initialize(person.getAddress());和person.getAddress()在同一個(gè)方法里面調(diào)用。他們往往出現(xiàn)在應(yīng)用程序的不同層次中(前者出現(xiàn)在DAO層居多,而后者則出現(xiàn)在web層居多).