【问题标题】:Spring Boot JPA - @Modifying(clearAutomatically = true) is not refreshing the cache valuesSpring Boot JPA - @Modifying(clearAutomatically = true) 不刷新缓存值
【发布时间】:2020-07-25 19:11:27
【问题描述】:

我正在使用 Spring Boot 数据 JPA 更新表中的列。 我的数据库是 Postgres。我正在尝试更新我的数据库中 statusCode 列的值。我将其从 1 更新为 6。 以下是相同的代码:

存储库

public interface MailRecordRepository extends JpaRepository<MailRecords, Integer> {

    // Fetch the rows which are new in status
    List<MailRecords> findTop100ByEmailStatusCode(int statusCode);

    // Update status to in-progress
    @Modifying(flushAutomatically = true, clearAutomatically = true) //, flushAutomatically = true
    @Query(value = "UPDATE users.usertbl SET statusCode = :inProgressStatusCode where " +
            "statusCode = 1 RETURNING *;", nativeQuery = true)
    public List<MailRecords> updateRecordsToInProgress(
            @Param("inProgressStatusCode") int inProgressStatusCode);
}

我正在尝试通过在 Postgres 支持的本机查询中使用 RETURNING 关键字来获取更新的行。我将查询返回的更新行分配给一个列表,并在控制台中打印它。但更新后的列表返回 statusCode 列的旧值,即 1 而不是更新后的值,即 6 以下是相同的代码:

服务类

public class MailServiceImpl implements MailService {

    @Autowired
    private MailRecordRepository mailRecordRepository;
    @Autowired
    private MailHandler mailHandler;
    @Autowired
    private EntityManager entityManager;

    @Override
    public List<MailRecords> getMailRecords() {
        return (List<MailRecords>) mailRecordRepository.findAll();
    }

    @Override
    public List<MailRecords> processEmailRecords() {
        //fetch records from DB which are in new status
        List<MailRecords> mailRecordsToBeSent = mailRecordRepository.findTop100ByEmailStatusCode(1);

        // update the status to in-progress
        //entityManager.clear();
        List<MailRecords> updatedMailRecords = mailRecordRepository.updateRecordsToInProgress(6);

        return updatedMailRecords;
    }

如果我使用实体管理器的 clear 方法,则会反映更新的值。但我想了解为什么@Modifying(flushAutomatically = true, clearAutomatically = true) 属性没有清除缓存值?为什么我必须显式调用entityManager.clear()? 谁能纠正我的理解并指出我哪里出错了?

【问题讨论】:

  • 能否请您澄清您正在比较的两个版本的代码,执行其中一个版本之前存在的数据以及两个版本的结果是什么?当前包含大量注释内容的单一版本代码令人困惑。
  • @JensSchauder 通过删除评论行并添加更多描述来更新帖子!

标签: postgresql spring-boot spring-data-jpa


【解决方案1】:

我有点惊讶返回实体确实有效。

但我有一个可能发生的理论,您可以使用调试器进行验证:

  1. 执行语句,更新数据库中的行
  2. 语句返回带有更新值的ResultSet
  3. JPA 实现(Hibernate?)忽略了除 id 之外的所有内容,并使用它们在一级缓存中查找实体并返回这些实体。
  4. Spring Data JPA 执行刷新并清除一级缓存。然后返回它在步骤 3 中从 JPA 实现中获得的任何内容。

您已经找到了解决方法。

【讨论】:

  • @Modifying(flushAutomatically = true, clearAutomatically = true) 应该理想地清除/刷新一级缓存中的对象,对吗?只是想了解为什么它不适用于更新查询
  • flush 和 clear 都不能在除了一级缓存之外的任何东西上工作。问题是它发生在您的语句执行并获得结果之后,因此它对您的结果没有影响。
猜你喜欢
  • 2018-12-25
  • 1970-01-01
  • 2019-10-20
  • 1970-01-01
  • 2019-05-28
  • 2011-08-06
  • 1970-01-01
  • 2018-11-09
  • 2021-12-24
相关资源
最近更新 更多