web-dev-qa-db-ja.com

Data Jpaのクエリに@Modifyingアノテーションを使用する必要があるのはなぜですか

たとえば、データベースからユーザーを削除するメソッドがCRUDインターフェイスにあります。

public interface CrudUserRepository extends JpaRepository<User, Integer> {

    @Transactional
    @Modifying
    @Query("DELETE FROM User u WHERE u.id=:id")
    int delete(@Param("id") int id, @Param("userId") int userId);
}

このメソッドは、アノテーション@Modifyingでのみ機能します。しかし、ここで注釈の必要性は何ですか?なぜスプリングがクエリを分析して、それが変更クエリであることを理解できないのですか?

33

これにより、選択クエリではなく、更新クエリとしてメソッドに注釈が付けられたクエリがトリガーされます。 EntityManagerには、変更クエリの実行後に古いエンティティが含まれる可能性があるため、自動的にクリアします(詳細については、EntityManager.clear()のJavaDocを参照)。これにより、EntityManagerで保留中のフラッシュされていないすべての変更が効果的に削除されます。 EntityManagerを自動的にクリアしたくない場合は、@ ModifyingアノテーションのclearAutomatically属性をfalseに設定できます。

詳細については、このリンクをたどることができます-

http://docs.spring.io/spring-data/jpa/docs/1.3.4.RELEASE/reference/html/jpa.repositories.html

33
Anshul Sharma

@Modifying注釈を必要とするクエリには、INSERT、UPDATE、DELETE、およびDDLステートメントが含まれます。

@Modifying注釈を追加すると、クエリがSELECTクエリ用ではないことを示します。

2

注意!

@Modifying(clearAutomatically=true)を使用すると、永続コンテキストの管理対象エンティティで保留中の更新がドロップされ、次のように表示されます。

そうすると、メソッドに注釈が付けられたクエリが、選択クエリではなく更新クエリとしてトリガーされます。 EntityManagerには、変更クエリの実行後に古いエンティティが含まれる可能性があるため、EntityManagerで保留中のすべての非フラッシュ変更を効果的に削除するため、自動的にクリアしません(詳細についてはEntityManager.clear()のJavaDocを参照)。 EntityManagerを自動的にクリアする場合は、@ ModifyingアノテーションのclearAutomatically属性をtrueに設定できます。

幸いなことに、Spring Boot 2.0.4.RELEASE Spring DataからflushAutomaticallyフラグが追加されました( https://jira.spring.io/browse/DATAJPA-806 )。変更クエリチェックリファレンスを実行する前の永続コンテキスト https://docs.spring.io/spring-data/jpa/docs/2.0.4.RELEASE/api/org/springframework/data/jpa/repository/Modifying .html#flushAutomatically

したがって、@Modifyingを使用する最も安全な方法は次のとおりです。

@Modifying(clearAutomatically=true, flushAutomatically=true)

ところで、Spring Dataのドキュメントは、これでドキュメントをまだ更新していません。

0
Youans