Meine Entität hat sowohl automatisch generierten Primärschlüssel (ID) als auch Geschäftsschlüssel (Namespace). Ich muss den Datensatz aktualisieren, indem ich den alten ersetze. Also, ich suche es nach Geschäftsschlüssel, lösche es und speichere eine neue Entität. Dies funktioniert, wenn jede Operation in ihrer eigenen Transaktion ausgeführt wird. Aber sobald ich alle in die gleiche Transaktion eingetragen habe, wurde delete() bis zur Ausführung von save() noch nicht ausgeführt, daher erhalte ich eine Constraint-Verletzung.Spring JpaRepository: delete() mit anschließendem save() in derselben Transaktion
transactionTemplate.execute(status -> {
MyEntity oldEntity = repository.findByNamespace(namespace);
if (oldEntity != null) {
repository.delete(oldEntity);
}
repository.save(newEntity);
return null;
});
ich es tatsächlich geschafft, es zu umgehen, indem
repository.flush();
Zugabe Aber ich wirklich nicht bekommen, warum ich diese flush() brauchen.
Ich denke, das ist, weil der JPA-Anbieter frei zu reorganisieren und/oder optimieren die Datenbank schreibt die ausstehenden Änderungen aus dem persistenten Kontext, insbesondere der JPA-Anbieter fühlt sich nicht verpflichtet, die Datenbank schreibt in der Reihenfolge und Form durchzuführen durch die individuellen Veränderungen des persistenten Kontextes impliziert. Jedenfalls ist die beschriebene Situation bekannt und die flush() ist eine bekannte Problemumgehung. – Michal