4

我的问题涉及 EntityManager.getReference。鉴于我在一个 JPA 会话中,我能否确定对于同一个实体和同一个主键对 EntityManager.getReference 的两次调用,我总是得到同一个 java 对象实例?对于两个不同的会话,我怀疑会获得两个不同的 java 对象实例——真的是这样吗?

我有兴趣了解一般规则,而不是任何特定实现的工作原理。它是否由规范定义?(我自己无法找到它)。

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");
}
4

1 回答 1

3

是的,这是 JPA 的基本保证——在持久性上下文(即会话)范围内,托管EntityManager实体的对象身份与其数据库身份匹配:

7.1 持久性上下文

持久性上下文是一组托管实体实例,其中任何持久性实体身份都有一个唯一的实体实例。

getReference()返回一个托管实例:

3.2.8 托管实例

...

contains() 方法可用于确定是否在当前持久性上下文中管理实体实例。

contains 方法返回 true:

  • 如果实体已从数据库中检索或已由 getReference 返回,并且尚未删除或分离。
  • 如果实体实例是新的,并且已在实体上调用了持久方法或已将持久操作级联到它。

此外,这种保证意味着在持久化上下文的范围内,无论您如何获得它(通过find()getReference()merge()、 查询或关系遍历),您都将获得相同 id 的相同实体实例。

例如,如果您从getReference()与该实体的所有进一步工作中获得代理,将通过该代理进行:

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

也可以看看:

于 2012-06-13T08:53:31.077 回答