У класса Foo есть один Бар. Поскольку Bar включен в другую сущность, также используется JoinTable. Когда клиент отправляет обновление Foo (без идентификаторов), сущность Foo извлекается из базы данных, и бар заменяется новым объектом (имеющий идентификатор ноль). В Spring Data Jpa сохранение выполняется в хранилище.
Это в принципе будет работать. Тем не менее, Bar имеет уникальное ограничение для двух своих столбцов. С этим ограничением сохранение (слияние) завершается неудачно, потому что эти два столбца не изменились. Причина в том, что hibernate first выполняет вставку для нового бара, а затем delete для старого бара. Следовательно, с ограничением вставка завершается неудачей.
При «реальном» обновлении (установка всех измененных атрибутов на панели из новых в старые) работает. Однако дерево объектов больше и отображение всех свойств будет утомительным (и потенциально подверженным ошибкам).
public class Foo {
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name = "FOO_BAR",
joinColumns = {@JoinColumn(name = "FOO_ID", referencedColumnName = "ID")},
inverseJoinColumns = {@JoinColumn(name = "BAR_ID", referencedColumnName = "ID")})
private Bar bar;
}
@Transactional
public void update(Foo fooToUpdate) {
// id's in fooToUpdate are null for both foo and bar
Foo foo = respository.findByName(fooToUpdate.getName());
foo.setBar(fooToUpdate.getBar());
repository.save(foo);
}
- Есть ли обходной путь? Будет ли альтернатива сопоставлению всех свойств от старых к новым значениям?
- Каков «правильный» способ сделать это?
Я знаю, что этот вопрос потенциально является дубликатом на Принудительный порядок выполнения в Merge-Statement , но я добавил некоторый код с конкретным отображением, который может отличаться от другого поста.