为什么我们必须在Data Jpa中对查询使用@Modifying注释

时间:2017-04-27 18:09:55

标签: java spring spring-data-jpa spring-annotations

例如我在我的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。但是这里的注释需要什么?为什么不能分析查询并理解它是一个修改查询?

3 个答案:

答案 0 :(得分:30)

这将触发向方法添加注释的查询,而不是选择查询。由于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

答案 1 :(得分:2)

需要@Modifying批注的查询包括INSERT,UPDATE,DELETE和DDL语句。

添加@Modifying注释表示该查询不适用于SELECT查询。

答案 2 :(得分:0)

  

注意!

使用@Modifying(clearAutomatically=true)将在持久性上下文中删除托管实体上所有未决的更新,春季指出:

  

这样做会触发注释该方法的查询作为更新   查询而不是选择一个。由于EntityManager可能包含   执行修改查询后,过时的实体   不会自动清除它(请参阅EntityManager.clear()的JavaDoc   (有关详细信息),因为这可以有效地丢弃所有未取消的更改   仍在EntityManager中挂起。如果您希望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文档尚未对此进行更新。