简体   繁体   English

Spring JpaRepository:delete(),在同一事务中使用后续的save()

[英]Spring JpaRepository: delete() with subsequent save() in the same transaction

My entity has both autogenerated primary key (id) and business key (namespace). 我的实体同时具有自动生成的主键(id)和业务键(命名空间)。 I need to update the record by replacing the old one. 我需要通过替换旧记录来更新记录。 So, I'm searching it by business key, delete it and save a new entity. 所以,我是按业务键搜索它,删除它并保存一个新实体。 This works if each operation in it's own transaction. 如果它自己的事务中的每个操作都有效。 But once I put all of them in the same transaction, by the time save() is executed, delete() wasn't executed yet, so I get a constraint violation. 但是,一旦我将所有这些都放在同一个事务中,在执行save()时,delete()还没有执行,所以我得到了一个约束违规。

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

I actually managed to bypass it by adding 我实际上设法通过添加绕过它

repository.flush();

But I don't really get why do I need this flush(). 但我真的不知道为什么我需要这个flush()。

Because repository.flush() flushes the changes to the database by calling EntityManager.flush(). 因为repository.flush()通过调用EntityManager.flush()来刷新对数据库的更改。 So when you flush the changes after delete(), sql gets executed and the following save will have no problems. 所以当你在delete()之后刷新更改时,会执行sql并且以下保存没有问题。

If you don't call flush it is up to persistence provider to determine when to flush the changes with transaction commit time being the deadline. 如果不调用flush,则由持久性提供程序决定何时刷新更改,事务提交时间为截止日期。 Also providers don't flush changes in any particular order, so it may happen that sometimes your operation succeeds and sometimes it doesn't. 提供者也不会以任何特定顺序刷新更改,因此有时您的操作会成功,有时则不会。 Usually, providers wait until the commit time flush, but you can influence that by setting a flush mode: 通常,提供程序会等到提交时间刷新,但您可以通过设置刷新模式来影响它:

for entitymanager
EntityManager.setFlushMode(FlushModeType type);

or for query
Query.setFlushMode(FlushModeType type);

There is an equivalent setting in Spring data JPA also, I'm sure, but I don't exactly know which one it is. 在Spring数据JPA中也有一个相同的设置,我敢肯定,但我不知道它是哪一个。

Note however, that immediately flushing the changes reduces the performance, so you should be careful when using it. 但请注意,立即刷新更改会降低性能,因此在使用时应小心。 In your particular case it is better to update the entity then it is to delete it and then persist the new one with the same business key. 在您的特定情况下,最好更新实体,然后删除它,然后使用相同的业务键保留新实体。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM