2014-01-28 60 views
3

我有幾個類,StudentAddress。爲了獲得一對多的關係,假設一個學生可以有很多地址。我爲這個結構創建了.hbm文件,但我想爲一個學生懶惰地加載地址。但它總是加載學生對象中的地址。我可以看到一些疑問被解僱了。就像從學生表和地址表中獲取信息一樣。Hibernate的一個一對多延遲加載與HBM

lazy=truelazy=false沒有任何影響,2個查詢始終點火(學生和地址)。

Student.hbm:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping> 
<class name="hibernate.s4.Student" table="STUDENT"> 

<id name="studentId" column="stdid"> 
    <generator class="increment" /> 
</id> 

<property name="studentName" column="stdname" length="10"/> 
<property name="phoneno" column="phno" length="10"/> 
<property name="degree" column="degree" length="10"/> 

<set name="addresses" cascade="save-update" lazy="false"> 
    <key column="studentId"></key> 
    <one-to-many class="hibernate.s4.Address"/> 
</set> 

</class> 
</hibernate-mapping> 

Address.hbm:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping> 
<class name="hibernate.s4.Address" table="ADDRESS"> 

<id name="addressid" column="addrid"> 
    <generator class="increment" /> 
</id> 

<property name="location" column="location" length="10"/> 
<property name="area" column="area" length="10"/> 
<property name="pin" column="pin" length="6"/> 

</class> 
</hibernate-mapping> 

客戶端類來保存數據,並獲取學生對象:

Transaction tx = session.beginTransaction(); 

Student std1 = new Student(); 
std1.setStudentName("balaji"); 
std1.setDegree("MCA"); 
std1.setPhoneno("XXX777CXCC"); 
session.save(std1); 

Address adr1 = new Address(); 
adr1.setArea("chirala"); 
adr1.setLocation("AP"); 
adr1.setPin(523155); 
adr1.setStudent(std1); 
Address adr3 = new Address(); 
adr3.setArea("pune"); 
adr3.setLocation("MH"); 
adr3.setPin(411028); 
adr3.setStudent(std1); 
std1.getAddresses().add(adr1); 
std1.getAddresses().add(adr3); 


System.out.println("Object saved successfully.....!!"); 
tx.commit(); 

Query query = session.createQuery("from Student where studentId = :studentId"); 
query.setParameter("studentId", 1); 
List list = query.list(); 
Student student = (Student)list.get(0); 
System.out.println((student.getAddresses() != null ? student.getAddresses().size() : 0)); 
+0

'student.getAddresses()'不會爲空,因爲即使對於未獲取的集合,Hibernate也使用代理對象。 – Durandal

回答

1

有幾個問題你代碼在最後的println上:System.out.println((student.getAddresses() != null ? student.getAddresses().size() : 0));

student.getAddresses()將永遠不會爲空,因爲Hibernate使用代理對象用於未提取的集合。在您的子集合上調用.size()將使hibernate在此時初始化集合。所以它不是空的開始,並呼籲.size()你迫使集合初始化。從Java Persistence with Hibernate

如果你打電話,是不是該標識符getter方法,如果你開始通過它的元素進行迭代,或者如果你調用任何集合的集合初始化任何方法代理初始化

報價 - 管理操作,如大小(),包含()

你可以嘗試設置地址lazy="extra"所以,當你調用.size()只會抓取集合的大小(即select count(*) from addresses),而不是整個集合本身。

+0

謝謝你的回答。它幫助我解決了這個問題。我有另一個問題。如果我們在類的層次上有些懶惰懶惰,並且希望對類中的另一個實體使用lazy,那麼equals()和hashcode()會產生什麼影響?例如:class Student將具有default-lazy = true/false,Address是一個實體應具有lazy = true(存在於Student類中)。在這種情況下,使用overriden方法(在Address類中)hashcode()和eqauls()會產生什麼影響? –

+0

@BalajiG是肯定會有一些影響。它圍繞着你認爲基於你的業務邏輯的「平等」。這裏有一些關於Hibernate文檔主題的相當不錯的文檔:[鏈接](http://docs.jboss.org/hibernate/core/4.0/manual/en-US/html/persistent-classes.html#persistent-類 - equalshashcode) – Durandal