合并实体,更改其ID,再次合并,导致"映射到数据库中的主键列.不允许更新"错误

Min*_*Sun 9 java hibernate jpa eclipselink java-ee

我有一个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);
Run Code Online (Sandbox Code Playgroud)

上面的代码不在事务上下文中.userManager是一个无状态会话bean,注入了EntityManager.执行时,控制台打印:

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.
Run Code Online (Sandbox Code Playgroud)

在第二次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);
Run Code Online (Sandbox Code Playgroud)

那么第一个场景和第二个场景之间有什么区别?根据JPA规范,只要实体处于分离状态,合并就应该成功,对吧?(假设存在ID = 2的实体)

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

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

我改变

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
Run Code Online (Sandbox Code Playgroud)

<provider>org.hibernate.ejb.HibernatePersistence</provider>    
Run Code Online (Sandbox Code Playgroud)

没有抛出任何错误.

Min*_*Sun 3

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

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
Run Code Online (Sandbox Code Playgroud)

<provider>org.hibernate.ejb.HibernatePersistence</provider>  
Run Code Online (Sandbox Code Playgroud)

没有抛出任何错误。

EclipseLink的版本是2.3.2。(随最新的 Glassfish 应用服务器 3.1.2 一起提供)。

目前最新的 hibernate 版本是 4.1.7。

  • 2.6.3版本仍然出现这种情况 (2认同)