java - Spring JpaRepository : delete() with subsequent save() in the same transaction

标签 java database spring transactions spring-data-jpa

我的实体同时具有自动生成的主键 (id) 和业务键(命名空间)。我需要通过替换旧记录来更新记录。所以,我正在按业务键搜索它,删除它并保存一个新实体。如果它自己的事务中的每个操作都有效。但是一旦我把它们都放在同一个事务中,当 save() 被执行时,delete() 还没有被执行,所以我得到了一个约束违规。

transactionTemplate.execute(status -> {
    MyEntity oldEntity = repository.findByNamespace(namespace);
    if (oldEntity != null) {
        repository.delete(oldEntity);
    }
    repository.save(newEntity);
    return null;
});

我实际上设法通过添加绕过它

repository.flush();

但我真的不明白为什么我需要这个 flush()。

最佳答案

因为 repository.flush() 通过调用 EntityManager.flush() 将更改刷新到数据库。所以当你在 delete() 之后刷新更改时,sql 会被执行,下面的保存不会有问题。

如果您不调用刷新,则由持久性提供者决定何时刷新更改,事务提交时间为截止日期。此外,提供程序不会以任何特定顺序刷新更改,因此有时您的操作可能会成功,有时可能会失败。通常,提供程序会等到提交时间刷新,但您可以通过设置刷新模式来影响它:

for entitymanager
EntityManager.setFlushMode(FlushModeType type);

or for query
Query.setFlushMode(FlushModeType type);

我敢肯定,Spring data JPA 中也有一个等效设置,但我不完全知道它是哪一个。

但请注意,立即刷新更改会降低性能,因此在使用时应小心。在您的特定情况下,最好更新实体,然后将其删除,然后使用相同的业务 key 保留新实体。

关于java - Spring JpaRepository : delete() with subsequent save() in the same transaction,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27718343/

相关文章:

java - Maven 使用其他模块的资源?

java - Web app需要与串口通信

php - 在数据库中保存 jquery json 数据

sql - Nativescript 离线数据

Spring @Transactional - javax.persistence.TransactionRequiredException

spring - 了解 Spring MVC 中的上下文

java - Spring 3 安全性不起作用

java - Spring Kafka - 防止消费者在 Spring Boot 构建期间连接 Kafka 主题

database - 免费的地理数据(首都、兴趣点……)数据库

java - 如何在 Nitrous.IO 中预览/运行 Java 程序?