EntityManager.getReference是否始终在会话中返回相同的实例?

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

最佳答案 是的,它是JPA的基本保证 – 在持久化上下文(即session,EntityManager)的范围内,托管实体的对象标识与其数据库标识匹配:

7.1 Persistence Contexts

A persistence context is a set of managed entity instances in which for any persistent entity identity there is a unique entity instance.

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

3.2.8 Managed Instances

The contains() method can be used to determine whether an entity instance is managed in the current persistence context.

The contains method returns true:

  • If the entity has been retrieved from the database or has been returned by getReference, and has not been removed or detached.
  • If the entity instance is new, and the persist method has been called on the entity or the persist operation has been cascaded to it.

而且,这个保证意味着在持久化上下文的范围内,无论你如何获得它,你都会得到相同id的实体实例(通过find(),getReference(),merge(),query或relationship遍历) .

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

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

也可以看看:

> JSR 317: JavaTM Persistence 2.0

点赞