简体   繁体   中英

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

My entity has both autogenerated primary key (id) and business key (namespace). 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.

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().

Because repository.flush() flushes the changes to the database by calling EntityManager.flush(). So when you flush the changes after delete(), sql gets executed and the following save will have no problems.

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. 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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