我的问题与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");
}
答案 0 :(得分:2)
是的,它是JPA的基本保证 - 在持久性上下文范围内(即会话,EntityManager
)托管实体的对象标识与其数据库标识匹配:
7.1持久性上下文
持久化上下文是一组托管实体实例,对于任何持久性实体标识,都有一个唯一的实体实例。
和getReference()
返回托管实例:
3.2.8受管实例
...
contains()方法可用于确定是否在当前持久化上下文中管理实体实例。
contains方法返回true:
- 如果已从数据库中检索实体或已由getReference返回该实体,并且尚未删除或分离该实体。
- 如果实体实例是新实例,并且已在实体上调用了persist方法,或者已将persist操作级联到该实体上。
此外,这种保证意味着在持久化上下文范围内,无论您如何获得它,您都将获得相同ID的实体实例(通过find()
,getReference()
,{{ 1}},查询或关系遍历)。
例如,如果您从merge()
获得代理,则该实体的所有进一步工作都将通过该代理进行:
getReference()
另见: