2012-06-13 49 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

非常感谢那个全面的答案 - 这非常有帮助 –

相关问题