2011-08-16 39 views
1

我在Spring 3.0.5中使用Hibernate 3.6。以編程方式指定休眠時多對一的延遲加載

我有以下映射用戶對象

<class name="foo.User" table="FOO_USER"> 
    <id column="USER_ID" name="id" type="java.lang.Integer"> 
     <generator class="identity"/> 
    </id> 


    <property name="firstName" column="FIRST_NAME" type="java.lang.String" length="100"/> 
    ... 
    <many-to-one name="organization" column="ORGANIZATION_ID class="foo.Organization" not-null="true" update="false" /> 
    ... 

用戶具有與組織的一個多對一的關係。通常情況下,我希望這種關係能夠被加載,所以映射的默認設置爲lazy = false(不指定任何內容)。

在某些情況下,我不想急於加載組織。我試圖用一個標準來指定它

(User)getSession().createCriteria(User.class) 
      .add(Restrictions.eq("id",id)) 
      .setFetchMode("organization", FetchMode.SELECT) 
      .uniqueResult(); 

但是取消模式被忽略。 Hibernate仍然急切地加載組織關係。幾個小時以來,我一直對此感到頭痛。任何幫助,將不勝感激。

回答

3

離開關聯映射爲懶惰並使用獲取策略調整性能總是最好的。我不認爲有一種方法可以將某些東西映射爲懶惰,然後在特定實例中使其變得懶惰。當然,fetch = select不會這樣做,因爲這並不意味着懶惰。請參閱參考手冊中的section 21.1 of "Improving Performance"以獲取有關概念的解釋。

+0

同意。當你需要這樣做時,讓事情變得遲緩並重寫。如果您絕對確定您會一直希望該協會填充,那麼協會只應該是EAGER。 – atrain

+1

非常感謝回覆。我同意一般情況下,關係應該保持懶惰。然而,在這種情況下,除了在某種情況下,我幾乎總是需要這種關係成爲EAGER。這太糟糕了,沒有辦法以編程方式讓關係懶散。至於fetch = select:我最初使用fetchmode = lazy,但在hibernate 3.6中,它已被棄用。 javadoc說要使用SELECT來代替。 (我最初嘗試使用fetchmode = LAZY,但那也行不通。) – MicGer

+1

其實,如果沒有辦法以編程方式建立關係LAZY,爲什麼會有FetchMode.LAZY值? – MicGer

1

FetchType可以編程方式使用fetchProfiles

例如爲:考慮有一個Employee類,它有兩個子類地址和部門獲取這些可以在Employee類設置的配置文件進行設置。

@FetchProfiles({ @FetchProfile(name = "emp_address", fetchOverrides = { @FetchProfile.FetchOverride(entity = Employee.class, association = "addresses", mode = FetchMode.JOIN) }), @FetchProfile(name = "emp_department", fetchOverrides = { @FetchProfile.FetchOverride(entity = Employee.class, association = "departments", mode = FetchMode.JOIN) })}) public class Employee { 

@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set addresses; 

@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set departments; } 

您可以啓用fetchprofile當您檢索員工記錄時。如果獲取配置文件啓用,那麼由於您正在進行連接,所以子對象正在熱切獲取。

session.enableFetchProfile("emp_address"); 
session.enableFetchProfile("emp_department"); 
Criteria criteria = session.createCriteria(Employee.class); 
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
List employees = criteria.list();