【问题标题】:Is there any use for Spring Data JPA's @Modifying without specifying it's attributes?Spring Data JPA @Modifying 是否有任何用途而不指定其属性?
【发布时间】:2021-04-20 12:31:54
【问题描述】:

AFAIK @Modifying@Query 注释中指定的 INSERT/UPDATE/DELETE 查询的情况下负责持久性上下文清理。
但是纯@Modifying 有什么用呢?根据this post,看来你应该总是写@Modifying(clearAutomatically=true, flushAutomatically=true)

文档说(link):

由于在执行修改查询后 EntityManager 可能包含过时的实体,我们不会自动清除它 ...因为这有效地删除了 EntityManager 中所有未刷新的更改 p>

所以默认情况下@Modifying 不清理(和do not flush)。那我为什么要把它添加到我的@Query 方法中呢?

【问题讨论】:

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


    【解决方案1】:

    (clearAutomatically=true, flushAutomatically=true) 将添加它们以使用 clearAutomatically 和 flushAutomatically 属性管理持久性上下文的状态。 这将清除/刷新一级缓存中的对象。

    通过使用 @Modify,spring boot 应用程序授予数据库写入权限以执行这些操作(UPDATE/INSERT/DELETE)。 @Query 可以单独使用 GET 并且必须使用 @modify 进行其他 3 次修改操作才能获得 DB 权限。

    【讨论】:

      【解决方案2】:

      @Querys 上的写操作是强制性的,这就是原因。

      clearAutomatically 和 flushAutomatically 允许您分别决定是否立即清除和立即刷新。如果设置为 false(默认值),那么 Spring Data 将在它认为合适的时候执行它,尝试优化对 DB 的访问操作。手术后可能不会马上清除,也可能是刚刷完,但还是会清除。

      【讨论】:

      • 谢谢。你是对的:mandatory for write operations
      • 但是clearAutomatically实际上在操作后清除,flushAutomatically在操作前刷新。
      【解决方案3】:

      @Modifying 注解用于增强@Query 注解,不仅可以执行 SELECT 查询,还可以执行 INSERT、UPDATE、DELETE 甚至 DDL 查询。

      让我们稍微玩一下这个注解,看看它是由什么组成的。

      首先,让我们看一个@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 名称派生查询方法不同。后者首先从数据库中获取实体,然后一个一个地删除它们。因此,这意味着将在这些实体上调用生命周期方法 @PreRemove。但是,对于前者,对数据库执行单个查询。

      最后,让我们使用 DDL 查询向我们的 USERS 表添加一个已删除的列:

      @Modifying
      @Query(value = "alter table USERS.USERS add column deleted int(1) not null default 0", nativeQuery = true)
      void addDeletedColumn();
      

      不幸的是,使用修改查询会使底层持久性上下文过时。但是,可以管理这种情况。

      【讨论】:

        猜你喜欢
        • 2021-12-24
        • 2018-01-26
        • 2017-10-09
        • 2017-08-29
        • 2019-08-21
        • 2017-10-07
        • 2018-12-25
        • 2018-04-18
        • 2019-05-31
        相关资源
        最近更新 更多