2014-10-28 73 views
56

休眠映射中的默認提取類型是什麼?Hibernate中的一對一,多對一和一對多默認提取類型

我得到了探索後知道的是:

  • 爲一到一個它是渴望
  • 一對多它是懶惰

但是在Eclipse中測試之後,它很渴望所有人。

這取決於我使用的是JPA還是Hibernate?

+1

如果您仍然參與JPA主題 - 我用新的答案更新了您的問題,因爲舊版本對於當前的Hibernate版本已過時。 – 2017-02-10 21:39:59

回答

94

這取決於您使用的是JPA還是Hibernate。

JPA 2.0 spec,默認值是:

OneToMany: LAZY 
ManyToOne: EAGER 
ManyToMany: LAZY 
OneToOne: EAGER 

而且在休眠,都是懶惰

+6

「而在休眠中,所有的都是懶惰的」顯然它在最近的版本中已經發生了變化。請參閱[AlexanderRühl的答案](http://stackoverflow.com/a/42168093/3136474)。 – Dinei 2017-05-05 15:58:01

+1

Hibernate是JPA實現之一,所以一旦你使用Hibernate,你使用的是JPA :) – xenteros 2017-08-10 09:28:45

14

要回答你的問題,Hibernate是JPA標準的一個實現。 Hibernate有其自身的運行怪癖,但每Hibernate docs

默認情況下,Hibernate使用了集合和延遲代理抓取的單值的關聯延遲select抓取。這些默認值對大多數應用程序中的大多數關聯都有意義。

因此,無論您聲明瞭哪種類型的關係,Hibernate都將使用延遲獲取策略加載任何對象。它將針對一對一或多對一關係中的單個對象使用惰性代理(應爲未初始化但不爲空),以及在您試圖訪問它時會使用值進行水合的空集合。

應該明白,除非你指定fetchType.EAGER,否則當你試圖訪問該對象時,Hibernate只會試圖用值填充這些對象。

28

我知道答案是在問這個問題時是正確的 - 但由於人(像我這一分鐘)仍然碰巧發現他們想知道爲什麼他們的WildFly 10的表現不同,我想給出當前Hibernate 5.x版本的更新:

Hibernate 5.2 User Guide中,它在11.2。應用抓取策略

Hibernate的建議是靜態標記所有協會 懶惰和使用動態抓取策略的渴望。這是 不幸與JPA規範不一致,該規範定義了 所有一對一和多對一關聯應該被熱切地提取 默認爲。作爲JPA提供者,Hibernate會尊重這個默認值。

,因爲Hibernate以及行爲像阿希什阿加瓦爾說上面JPA:

OneToMany: LAZY 
ManyToOne: EAGER 
ManyToMany: LAZY 
OneToOne: EAGER 

(見JPA 2.1 Spec

+0

如果我們使用本地hibernate而不是JPA impl,那麼它的行爲方式是什麼? – jMounir 2017-03-02 15:22:27

+0

@jMounir:嗯,我還沒有嘗試過,但由於Hibernate聲明它的行爲與JPA中定義的行爲類似,所以我不明白當爲自己使用Hibernate時會有什麼不同。在兩種情況下都可以覆蓋默認策略。 – 2017-03-07 11:51:46

0

對於單值的關聯,即,一to-One和多對一-One: -
Default Lazy =代理
代理延遲加載: - 這意味着您的關聯實體的代理對象是loa DED。這意味着只有連接兩個實體的id被加載到關聯實體的代理對象。
例如:A和B是具有多對一關聯的兩個實體。即:有可能是多個A的每一個B. A的每個對象將包含 `

public class A{ 
    int aid; 
    //some other A parameters; 
    B b; 
} 
public class B{ 
    int bid; 
    //some other B parameters; 
} 

'
的關係B.
的引用將包含列(援助,中標,...實體A的其他列)。
關係B將包含列(bid,...實體B的其他列)

代理暗示何時提取A,只有id被提取出來並存儲到B中僅包含id的代理對象中。 B的代理對象是代理類的對象,它是B的子類,只有最少的字段。 由於出價已經是關係A的一部分,因此沒有必要觸發查詢以從關係B獲得出價。 僅當訪問除出價之外的字段時,實體B的其他屬性才被延遲加載。

對於集合,即一對多一對多和1對多: -
默認懶惰=真


也請注意,抓取策略(選擇,加盟等)可以重寫懶惰。 ie:如果lazy ='true'並且fetch ='join',則A的獲取也將獲取B或Bs(在集合的情況下)。如果你仔細想想,你可以得到原因。
單值關聯的默認提取是「連接」。
集合的默認提取是「select」。 請確認最後兩行。我從邏輯上推斷出這一點。