2

当存在具有相同主键的现有实体时,我primaryKeyUpdateDisallowed ValidationException尝试将实体合并到数据库中。

当然,当我执行 aTypedQuery并让实体管理器首先返回实体,更新适当的值,然后合并时,我不会得到异常。问题是这个过程在资源方面太昂贵了。我需要能够简单地合并而不会产生异常。

有没有办法构造我们的实体类,以便我们可以覆盖记录,包括主键?或者其他解决问题的方法?

4

1 回答 1

0

在 JPA 中,如果您希望这样做:

entityManager.merge(someEntity);

那么您必须首先将 someEntity 从数据库加载到 entityManager 持久性上下文中,然后通过“entityManager.detach(someEntity)”或清除持久性上下文进行分离。如果 someEntity 没有预先加载和分离,而是通过“new SomeEntity()”创建,则 merge() 函数将确定您添加了新实体并执行非常类似于 entityManager.persist(某个实体)。当数据在事务中被刷新或提交时,它会生成一个 SQL INSERT,这将与预先存在的 PK 冲突。

这是 JPA 2 规范中的指定行为:


应用于实体 X 的合并操作的语义如下:

  • 如果 X 是分离实体,则 X 的状态被复制到具有相同身份的预先存在的受管实体实例 X' 上,或者创建 X 的新受管副本 X'。
  • 如果 X 是一个新的实体实例,则创建一个新的托管实体实例 X',并将 X 的状态复制到新的托管实体实例 X'。

> 问题是这个过程在资源方面过于昂贵。我需要能够简单地合并而不会产生异常。

这不应该是这样。从数据库中检索实体或实体列表应该是有效的。可能您的查询可以改进。查询中有“where”子句吗?刷新期间是否有很多实体级联(通过 @OneToMany 或 @ManyToOne 等关系上的属性 cascade=CascadeType.REFRESH/ALL)?您是否有一个包含许多实体/表的非常复杂的继承层次结构?如果您可以提供您的 JPQL 或条件查询,我相信问题将很容易解决。:-)

于 2012-10-15T00:19:32.593 回答