【问题标题】:EntityManager.getReference does it always return the same instance within a session?EntityManager.getReference 它是否总是在会话中返回相同的实例?
【发布时间】:2012-06-16 03:50:41
【问题描述】:

我的问题涉及 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");
}

【问题讨论】:

标签: session object jpa reference entitymanager


【解决方案1】:

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

7.1 持久性上下文

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

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

3.2.8 托管实例

...

contains() 方法可以用来判断一个实体实例是否在当前持久化上下文中被管理。

contains 方法返回 true:

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

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

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

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

另请参阅:

【讨论】:

  • 非常感谢您提供全面的答案 - 这非常有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-22
  • 1970-01-01
  • 1970-01-01
  • 2020-09-20
  • 2016-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多