1. 概要

Spring Data JPAをHibernateで使用すると、Hibernateの追加機能も使用できます。 @DynamicUpdateはそのような機能の1つです。

@DynamicUpdate は、JPAエンティティに適用できるクラスレベルのアノテーションです。 Hibernateがエンティティの更新のために生成するSQLステートメントの変更された列のみを使用するようにします

この記事では、 Spring Data JPA の例を使用して、@DynamicUpdateアノテーションを確認します。

2. JPA @Entity

アプリケーションが起動すると、HibernateはすべてのエンティティのCRUD操作用のSQLステートメントを生成します。 これらのSQLステートメントは一度生成され、パフォーマンスを向上させるためにメモリにキャッシュされます。

生成された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
}

次に、アカウントエンティティの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ステートメントには、アカウントのすべての列が含まれます。

update Account set active=?, name=?, type=? where id=?

3. JPA @Entity@DynamicUpdate

name フィールドのみを変更したにもかかわらず、HibernateはSQLステートメントにすべての列を含めていることがわかりました。

次に、@DynamicUpdateアノテーションをAccountエンティティに追加しましょう。

@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の動作を確認しました。 また、この機能を使用する必要がある場合と使用しない場合についても説明しました。

いつものように、このチュートリアルで使用される完全なコード例は、Githubから入手できます。