我有一个 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 是一个注入了 EntityManager 的无状态会话 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>
没有抛出任何错误。