2

primaryKeyUpdateDisallowed ValidationException同じ主キーを持つ既存のエンティティがある場合に、エンティティをデータベースにマージしようとするとエラーが発生します。

もちろん、TypedQueryエンティティ マネージャーを実行して、最初にエンティティを返し、適切な値を更新してからマージしても、例外は発生しません。問題は、このプロセスがリソース的にコストが高すぎることです。結果の例外なしで簡単にマージできる必要があります。

主キーを含むレコードを上書きできるように、エンティティ クラスを構造化する方法はありますか? または、問題を回避する他の方法はありますか?

4

1 に答える 1

0

JPA で、次のことを行いたい場合:

entityManager.merge(someEntity);

次に、最初に someEntity を DB から entityManager 永続コンテキストにロードし、次に「entityManager.detach(someEntity)」を介して、または永続コンテキストをクリアしてデタッチする必要があります。someEntity がプリロードおよびデタッチされておらず、代わりに「new SomeEntity()」によって作成されている場合、merge() 関数は、新しいエンティティが追加されたと判断し、entityManager.persist( と非常によく似た内部操作を実行します。 someEntity)。データがトランザクションでフラッシュまたはコミットされると、SQL INSERT が生成され、既存の PK と衝突します。

JPA 2仕様から指定された動作は次のとおりです。


エンティティ X に適用されるマージ操作のセマンティクスは次のとおりです。

  • X が切り離されたエンティティである場合、X の状態は同じ ID の既存のマネージド エンティティ インスタンス X' にコピーされるか、X の新しいマネージド コピー X' が作成されます。
  • X が新しいエンティティ インスタンスの場合、新しい管理エンティティ インスタンス X' が作成され、X の状態が新しい管理エンティティ インスタンス X' にコピーされます。

> 問題は、このプロセスがリソース的にコストが高すぎることです。結果の例外なしで簡単にマージできる必要があります。

これはあってはならないことです。DB からエンティティまたはエンティティのリストを取得することは効率的です。クエリが改善される可能性があります。クエリに「where」句はありますか? (@OneToMany や @ManyToOne などの関係で属性 cascade=CascadeType.REFRESH/ALL を介して) 更新中にエンティティのカスケードが多くありますか? 多くのエンティティ/テーブルを含む非常に複雑な継承階層がありますか? JPQL または基準クエリを提供できれば、問題は簡単に修正できると確信しています。:-)

于 2012-10-15T00:19:32.593 に答える