Spring Data JPAを使用した@DynamicUpdate

1. 概要

HibernateでSpring Data JPAを使用する場合、Hibernateの追加機能も使用できます。 _ @ DynamicUpdate_はそのような機能の1つです。
_ @ DynamicUpdate_は、JPAエンティティに適用できるクラスレベルの注釈です。 * Hibernateは、エンティティの更新用に生成したSQLステートメントの変更された列のみを使用するようにします*。
この記事では、* https://www.baeldung.com/the-persistence-layer-with-spring-data-jpa [Spring Data JPA ] *例。

*2. JPA _ @ Entity_ *

アプリケーションが起動すると、HibernateはすべてのエンティティのCRUD操作用のSQLステートメントを生成します。 これらのSQLステートメントは1回生成され、パフォーマンスを向上させるためにメモリにキャッシュされます。
生成されたSQL更新ステートメントには、エンティティのすべての列が含まれます。 エンティティを更新する場合、変更された列の値はSQL更新ステートメントに渡されます。 更新されない列の場合、Hibernateは既存の値を使用して更新します。
これを例で理解してみましょう。 まず、_Account_という名前のJPAエンティティを考えてみましょう。
@Entity
public class Account {

    @Id
    private int id;

    @Column
    private String name;

    @Column
    private String type;

    @Column
    private boolean active;

    // Getters and Setters
}
次に、_Account_エンティティのJPAリポジトリを作成します。
@Repository
public interface AccountRepository extends JpaRepository<Account, Integer> {
}
ここで、_AccountRepository_を使用して、_Account_オブジェクトの_name_フィールドを更新します。
Account account = accountRepository.findOne(ACCOUNT_ID);
account.setName("Test Account");
accountRepository.save(account);
この更新を実行した後、生成されたSQLステートメントを確認できます。 生成されたSQLステートメントには、_Account_のすべての列が含まれます。
update Account set active=?, name=?, type=? where id=?

3. JPA _ @ Entity_ with _ @ DynamicUpdate_

_name_フィールドのみを変更したにもかかわらず、Hibernateがすべての列をSQLステートメントに含めていることがわかりました。
それでは、_Account_エンティティに_ @ DynamicUpdate_注釈を追加しましょう。
@Entity
@DynamicUpdate
public class Account {
    // Existing data and methods
}
次に、前のセクションで使用したのと同じ更新コードを実行しましょう。 この場合、Hibernateによって生成されたSQLには_name_列のみが含まれていることがわかります。
update Account set name=? where id=?
それで、*エンティティで_ @ DynamicUpdate_を使用すると*どうなりますか?
実際、エンティティで_ @ DynamicUpdate_を使用する場合、Hibernateは更新にキャッシュされたSQLステートメントを使用しません。 代わりに、エンティティを更新するたびにSQLステートメントを生成します。 この*生成されたSQLには、変更された列のみが含まれます*。
変更された列を見つけるために、Hibernateは現在のエンティティの状態を追跡する必要があります。 したがって、エンティティのフィールドを変更すると、エンティティの現在の状態と変更された状態が比較されます。
つまり、* @ _ DynamicUpdate_にはパフォーマンスオーバーヘッドが関連付けられています*。 したがって、実際に必要な場合にのみ使用してください。
確かに、この注釈を使用する必要があるシナリオがいくつかあります。たとえば、エンティティが多数の列を持つテーブルを表し、これらの列のうちのいくつかのみを頻繁に更新する必要がある場合です。 また、バージョンなしの楽観的ロックを使用する場合は、_ @ DynamicUpdate_を使用する必要があります。

4. 結論

このチュートリアルでは、Hibernateの_ @ DynamicUpdate_アノテーションを調べました。 Spring Data JPAの例を使用して、_ @ DynamicUpdate_の動作を確認しました。 また、この機能をいつ使用すべきか、使用すべきではないかについても説明しました。
いつものように、このチュートリアルで使用される完全なコード例はhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/spring-hibernate-5[Github上]で入手できます。