Spring JpaRepository: delete() с последующим сохранением() в той же транзакции
моя сущность имеет как автогенерированный первичный ключ (id), так и бизнес-ключ (пространство имен). Мне нужно обновить запись, заменив старый. Итак, я ищу его по бизнес-ключу, удаляю его и сохраняю новый объект. Это работает, если каждая операция в своей собственной транзакции. Но как только я помещаю их все в одну транзакцию, к моменту выполнения save() delete () еще не был выполнен, поэтому я получаю нарушение ограничения.
transactionTemplate.execute(status -> {
MyEntity oldEntity = repository.findByNamespace(namespace);
if (oldEntity != null) {
repository.delete(oldEntity);
}
repository.save(newEntity);
return null;
});
мне действительно удалось обойти его добавление
repository.flush();
но я действительно не понимаю, зачем мне нужен этот флеш ().
1 ответов
потому что репозитории.flush () сбрасывает изменения в базу данных, вызывая EntityManager.вспыхнуть.)( Поэтому, когда вы очищаете изменения после delete (), sql выполняется, и следующее сохранение не будет иметь проблем.
Если вы не вызываете flush, поставщик персистентности должен определить, когда нужно сбросить изменения с временем фиксации транзакции, являющимся крайним сроком. Также поставщики не сбрасывают изменения в каком-либо определенном порядке, поэтому может случиться, что иногда ваша операция завершается успешно и иногда нет. Обычно поставщики ждут, пока время фиксации не будет сброшено, но вы можете повлиять на это, установив режим сброса:
for entitymanager
EntityManager.setFlushMode(FlushModeType type);
or for query
Query.setFlushMode(FlushModeType type);
в Spring data JPA также есть эквивалентная настройка, я уверен, но я точно не знаю, какая из них.
обратите внимание, однако, что немедленная очистка изменений снижает производительность, поэтому вы должны быть осторожны при ее использовании. В вашем конкретном случае лучше обновить сущность, а затем удалить ее, а затем сохранить новую с тем же ключом.