2012-06-13 84 views
4

我的問題涉及到EntityManager.getReference。鑑於我在一個JPA會話中,我可以確定對於同一個實體和相同主鍵的兩次EntityManager.getReference調用,我總是得到相同的java對象實例嗎? 對於兩個截然不同的會話,我懷疑會得到兩個不同的java對象實例 - 是真的嗎?EntityManager.getReference它是否總是返回一個會話中的同一個實例?

我有興趣瞭解一般規則,而不是具體的實現如何工作。它是否由規範定義? (我自己找不到)。

Person p1 = EntityManager.getReference(Person.class, 1L); 
Person p2 = EntityManager.getReference(Person.class, 1L); 

if (p1 == p2) { 
    System.out.println("SAME"); 
} else { 
    System.out.println("DIFF"); 
} 
+0

也許這將有助於:http:// stackoverflow。com/questions/1607532/when-to-use-entitymanager-find-vs-entitymanager-getreference – JMelnik

回答

2

是的,這是JPA的一個基本保障 - 持久化上下文的範圍內(即會話,EntityManager)的對象標識管理實體符合其數據庫身份:

7.1的持久化上下文

持久化上下文是一組託管實體實例,其中對於任何持久實體身份都有一個唯一的實體實例。

getReference()返回一個託管實例:

3.2.8管理實例

...

的含有()方法可用於確定是否一個實體實例在當前的持久化上下文中進行管理。

contains方法返回true:

  • 如果實體已經從數據庫中檢索或已getReference返回,並沒有被移除或分離。
  • 如果實體實例是新的,並且在實體上調用了persist方法,或者persist操作已被級聯到實體上。

此外,本次擔保是指持久化上下文的範圍內,你會得到實體相同ID的同一個實例,無論你如何得到它(通過find()getReference()merge(),查詢或關係遍歷)。

例如,如果從getReference()獲得代理與實體所有工作將通過代理髮生:

Person p1 = EntityManager.getReference(Person.class, 1L); 
Person p2 = EntityManager.find(Person.class, 1L); 
assertSame(p1, p2); 

參見:

+0

非常感謝那個全面的答案 - 這非常有幫助 –

相關問題