gpt4 book ai didi

java - 合并实体,更改其id,再次合并,导致 "mapped to a primary key column in the database. Updates are not allowed"错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:19:54 25 4
gpt4 key购买 nike

我有一个 JPA 程序,其中 EclipseLink 是持久性提供程序。当我合并用户实体、更改其 ID 并尝试再次合并同一用户实例时,会引发错误。我重写了我的代码,以最简单的方式说明我的问题。

User user = userManager.find(1);
userManager.merge(user);
System.out.println("User is managed? "+userManager.contains(user);
user.setId(2);
userManager.merge(user);

以上代码不在事务上下文中。 userManager 是一个注入(inject)了 EntityManager 的无状态 session bean。执行时,控制台打印:

User is managed? false

Exception [EclipseLink-7251] (Eclipse Persistence Services - 2.1.3.v20110304-r9073): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The attribute [id] of class [demo.model.User] is mapped to a primary key column in the database. Updates are not allowed.

异常发生在第二次 merge() 调用时。

如果我创建一个新用户,设置它的 ID 并合并它,它会起作用:

User user = userManager.find(1);
userManager.merge(user);
System.out.println("User is managed? "+userManager.contains(user);
User newUser = new User();
newUser.setId(2);
userManager.merge(newUser);

那么第一种情况和第二种情况有什么区别呢?按照JPA规范,只要实体处于分离状态,合并就应该成功,对吧?(假设ID=2的实体存在)

为什么 EclipseLink 提供者似乎对用户实体之前已合并的事实感到困扰?

更新:这似乎是 EclipseLink 的一个错误。我已将持久性提供程序从 EclipseLink 替换为 Hibernate:

我改变

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

<provider>org.hibernate.ejb.HibernatePersistence</provider>    

没有抛出错误。

最佳答案

原因是 Id 可能被插入/定义 - 正如您在第二个示例中所做的那样,但没有更改/更新 - 正如您在第一个示例中尝试的那样。 JPA 提供程序试图反射(reflect)数据库中的更改但失败了。

JPA 2 规范 §2.4 说

The application must not change the value of the primary key. The behavior is undefined if this occurs.

关于java - 合并实体,更改其id,再次合并,导致 "mapped to a primary key column in the database. Updates are not allowed"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12364051/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com