2010-02-09 43 views
11

在Hibernate中,當您通過負載檢索實體,如果你訪問該實體的ID訪問它不會初始化代理:什麼時候檢索一個Hibernate代理的id初始化代理?

Property myProp = (Property) session.load(Property.class, myId); 
myProp.getId(); // Doesn't load the proxy 
myProp.getDescription(); // Loads the proxy from the database hit 

但是,我不清楚規則是什麼裝載協會代理。我的印象是,當您通過HQL查詢或標準檢索實體時,適用相同的規則。

在我的代碼中的每個Property有一個Company。該Company被宣佈爲:

@ManyToOne(fetch = FetchType.LAZY, optional=false) 
@JoinColumn(name = "company_id", nullable=false) 
private Company company; 

然而,在我的代碼通過Properties迭代,因爲當我打電話Company.getId()Company被加載時,我目前得到N + 1種選擇。

CompanyProperty對象中,id字段是一個用@Id註解的Long。

爲了防止加載Company實體,是否還有其他一些考慮因素?

+0

答案是一個很好的開始,但第一個評論是最好的答案。請務必閱讀Gennady Shumakher發佈的鏈接。 此外,如果有人很好奇,我發現在這個問題上的Hibernate數據庫有一個錯誤:http://opensource.atlassian.com/projects/hibernate/browse/HHH-3718 – jbarz 2010-02-11 15:35:46

回答

10

由於不能按預期方式正常工作,您必須使用屬性訪問而不是字段訪問。

而不是

@ManyToOne(fetch=FetchType.LAZY, optional=false) 
@JoinColumn(name="COMPANY_ID", nullable=false) 
private Company company; 

使用

@ManyToOne(fetch=FetchType.LAZY, optional=false) 
@JoinColumn(name="COMPANY_ID", nullable=false) 
public Company getCompany() { 
    return this.company; 
} 

照顧你不能在同一時間使用屬性訪問和現場存取權限。所以你應該選擇一種方法

問候,

+2

+1 - 更詳細的解釋是可用的這裏:http://www.catalysts.cc/en/blog/ejb-annotations-hibernate-lazy-loading/ – 2010-02-10 10:05:16

+0

我從閱讀文章中看到,似乎正確的做法實際上是更改公司對象,以便註釋都在吸氣劑上。更重要的是getId()方法在Property上註釋而不是getCompany()。 – jbarz 2010-02-11 14:35:40

+1

Java Persistence with Hibernate - (www.manning.com/bauer2)在「13.1.3瞭解代理」中提到了這一點:「只要你只訪問數據庫標識符屬性,就不需要代理初始化。 (請注意,如果您將 標識符屬性映射爲直接字段訪問,則這不是真實的; Hibernate甚至不知道存在getId()方法的 如果調用它,代理服務器必須初始化。 。 – 2014-09-15 20:18:56

相關問題