为什么 merge() return 复制对象?

Why merge() return copy object?

我是 JPA 的新手,阅读了 EntityManager 中存在的合并方法,当我们尝试合并分离的对象时,return 复制对象。 为什么它 return 是一个复制对象?

我尝试分离一个托管对象,发现分离对象的哈希码与通过合并方法 return 合并的对象的哈希码不同。

Employee emp = new Employee();
emp.setName("Name");

em.persist(emp);

emp = em.find(Employee.class, emp.getId());
em.detach(emp);

emp.setName("New Name");

int empHashCode = emp.hashCode();

Employee managedEmp = em.merge(emp);
int managedHashCode = managedEmp.hashCode();

if(empHashCode == managedHashCode){
    System.out.println("Hash Code Equal");
} else{
    System.out.println("Hash Code not Equal");
}

输出为"Hash Code not Equal"。 这意味着两个对象都不同,但为什么呢?

merge() returns复制对象,请看下面的解释

Applications may not access an entity directly from multiple threads while it is managed by a persistence context. An application may choose, however, to allow entities to be accessed concurrently when they are detached. If it chooses to do so, the synchronization must be controlled through the methods coded on the entity. Concurrent entity state access is not recommended, however, because the entity model does not lend itself well to concurrent patterns. It would be preferable to simply copy the entity and pass the copied entity to other threads for access and then merge any changes back into a persistence context when they need to be persisted.

以上解释复制自"Pro JPA 2 in Java EE 8: An In-Depth Guide to Java Persistence APIs"

除了@yashjain12yj 添加的答案

有很多情况需要考虑。

  • 如果实体已经在持久性上下文(会话)中,则不执行任何操作,级联除外
  • 如果实体被分离,则返回一个副本(对象'),它被附加(管理)
  • 如果实体是临时的(新实例),则保存它并返回持久(和托管)副本
  • 如果实体被分离,但当前实体管理器中存在具有相同标识符的对象,则将分离对象的状态复制到当前持久实体中,并返回它(当前)

更多详情here