質問
Colum名の値を「PCName」としているテーブルのすべてのフィールドを更新したいと思います。更新したいテーブル名はxyzです。いくつかのフィールドのみを更新し、変更されていないフィールドを保持しません。
これは多くの行に影響し、単一の行ではなく、name = 'pcname'の多くの行があるため、JPA.iを使用して実行できます。私はこのテーブルに関連付けられているエンティティクラスを持っています。
解決
オブジェクト指向の方法でそれを行うか、更新クエリを使用することができます。
オブジェクト指向:
public void setNameOfAllEntities(String newname){
List<MyEntity> items =
entityManager.createQuery("from MyEntity", MyEntity.class)
.getResultList();
for(MyEntity entity : items){
entity.setName(newname);
}
}
更新クエリ(テストされていない):
public void setNameOfAllEntities(final String newname){
final int changes =
entityManager.createQuery("update MyEntity set name = :name")
.setParameter("name", newname)
.executeUpdate();
System.out.println(changes + " rows changed");
}
明らかに、2番目のバージョンのパフォーマンスが向上します。
他のヒント
ショーナイザー 答え 正しい(+1)、このユースケースにはバルクアップデートが本当にいいでしょう。ただし、バルクアップデート操作で予防策を講じる必要があります。 JPA仕様を言い換えるには:
- バルクの更新は、楽観的なロックチェックをバイパスします (したがって、バージョンの列を手動で増やすか、必要に応じてバージョン列を手動で検証する必要があります)
- 永続性のコンテキストは、バルク操作の結果と同期されません (したがって、影響を受ける可能性のあるエンティティの状態をロードする前に、別のトランザクションまたはトランザクションの開始時にバルク操作を実行する必要があります)。
したがって、私の提案は、少なくともバージョン列を増やして、他のスレッドとの並行性の問題を回避することです。
UPDATE XYZ xyz
SET xyz.name = :newname, xyz.version = xyz.version + 1
また、別のトランザクションで実行するか、以前に説明したようにXYZをロードする前に実行します。
参照
- JPA 1.0仕様
- セクション4.10「バルクの更新および削除操作」
所属していません StackOverflow