Spring Data JPA @Modifying Annotation

1. 前書き

この短いチュートリアルでは、* Spring Data JPA _ @ Query_アノテーションを使用して更新クエリを作成する方法を学習します*。 _ @ Modifying_アノテーションを使用してこれを実現します。
まず、メモリを更新し、https://www.baeldung.com/spring-data-jpa-query [Spring Data JPAを使用してクエリを作成する方法]を確認します。 その後、_ @ Query_および_ @ Modifying_アノテーションの使用について詳しく説明します。 最後に、クエリの変更を使用するときに永続コンテキストの状態を管理する方法について説明します。

2. Spring Data JPAでのクエリ

最初に、データベース内のデータを照会するためにSpring Data JPAが提供する* 3メカニズムを要約しましょう*:
  • クエリメソッド

  • _ @ Query_アノテーション

  • カスタムリポジトリの実装

    _User_クラスと一致するSpring Data JPAリポジトリを作成して、これらのメカニズムを説明しましょう。
@Entity
@Table(name = "users", schema = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
    private LocalDate creationDate;
    private LocalDate lastLoginDate;
    private boolean active;
    private String email;

}
public interface UserRepository extends JpaRepository<User, Integer> {}
クエリメソッドメカニズムを使用すると、メソッド名からクエリを取得してデータを操作できます。
List<User> findAllByName(String name);
void deleteAllByCreationDateAfter(LocalDate date);
この例では、名前でユーザーを取得するクエリ、または特定の日付より後の作成日を持つユーザーを削除するクエリを見つけることができます。
_ @ Query_アノテーションについては、*特定のJPQLまたはSQLクエリを_ @ Query_アノテーションに書き込む可能性があります*:
@Query("select u from User u where u.email like '%@gmail.com'")
List<User> findUsersWithGmailAddress();
このコードスニペットでは、[email protected]_メールアドレスを持つユーザーを取得するクエリを見ることができます。
最初のメカニズムにより、データを取得または削除できます。 2番目のクエリについては、ほぼすべてのクエリを実行できます。 ただし、クエリを更新するには、_ @ Modifying_アノテーションを追加する必要があります*。 これがこのチュートリアルのトピックになります。

3. _ @ Modifying_アノテーションの使用

  • @Modifying_アノテーションは、 @を強化するために使用されます_SELECT_クエリだけでなく、INSERT _、 UPDATE DELETE_、さらには_DDL_クエリも実行するQuery_アノテーション。*

    このアノテーションを少し試して、それが何でできているのか見てみましょう。
    最初に、_ @ Modifying_ UPDATEクエリの例を見てみましょう。
@Modifying
@Query("update User u set u.active = false where u.lastLoginDate < :date")
void deactivateUsersNotLoggedInSince(@Param("date") LocalDate date);
ここでは、特定の日付以降にログインしていないユーザーを非アクティブ化しています。
非アクティブ化されたユーザーを削除する別の方法を試してみましょう。
@Modifying
@Query("delete User u where u.active = false")
int deleteDeactivatedUsers();
ご覧のとおり、このメソッドは整数を返します。 *これは、Spring Data JPA _ @ Modifying_クエリの機能であり、更新されたエンティティの数を提供します。*
_ @ Query_を使用して削除クエリを実行すると、Spring Data JPAの_deleteBy_名前派生クエリメソッドとは異なる動作をすることに注意する必要があります。 後者は、最初にデータベースからエンティティをフェッチしてから、それらを1つずつ削除します。 したがって、これは、ライフサイクルメソッド_ @ PreRemove_がそれらのエンティティで呼び出されることを意味します。 ただし、前者では、データベースに対して単一のクエリが実行されます。
最後に、_DDL_クエリを使用して_USERS_テーブルに_deleted_列を追加しましょう。
@Modifying
@Query(value = "alter table USERS.USERS add column deleted int(1) not null default 0", nativeQuery = true)
void addDeletedColumn();
残念ながら、変更クエリを使用すると、基になる永続コンテキストが古くなります。 ただし、この状況を管理することは可能です。 それが次のセクションの主題です。

4. 永続コンテキストの管理

*クエリの変更により永続コンテキストに含まれるエンティティが変更されると、このコンテキストは古くなります。*この状況を管理する1つの方法は、https://docs.oracle.com/javaee/7/api/javax/persistence/EntityManagerです。 html#clear-[永続化コンテキストをクリア]。 そうすることで、永続コンテキストが次回データベースからエンティティをフェッチするようにします。
ただし、_EntityManager_で_clear()_メソッドを明示的に呼び出す必要はありません。 _ @ Modifying_アノテーションからhttps://codingexplained.com/coding/java/spring-framework/updating-entities-with-update-query-spring-data-jpa[_clearAutomatically_ property]を使用するだけです。
@Modifying(clearAutomatically = true)
*そのようにして、クエリの実行後に永続コンテキストがクリアされるようにします。*
しかし、永続コンテキストにフラッシュされていない変更が含まれている場合はどうでしょうか? したがって、それをクリアすると、保存されていない変更がドロップされます。 幸いなことに、使用できる注釈の別のプロパティがあります-â_flushAutomatically_:
@Modifying(flushAutomatically = true)
*今、_EntityManager_はクエリが実行される前にフラッシュされます。*

5. 結論

_ @ Modifying_アノテーションに関するこの短い記事はこれで終わりです。 この注釈を使用して、_INSERT、UPDATE、DELETE、_、さらには_DDL_などの更新クエリを実行する方法を見てきました。 その後、_clearAutomatically_および_flushAutomatically_プロパティを使用して、永続コンテキストの状態を管理する方法を学びました。
いつものように、この記事の完全なコードはhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/spring-data-jpa[GitHubで]から入手できます。