Предположим следующую модель:
@Entity
public class A {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "a", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private List<B> bs;
public B getB(long id) {
for(B b : bs)
if(b.getId() == id) {
return b;
}
}
}
@Entity
public class B {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "a_id")
private A a;
private String someString;
}
Затем я пытаюсь обновить свойство некоторой сущности B:
@Transactional(rollbackFor = Exception.class)
public void doSomeWork() {
A a = aRepository.findById(/* some id */);
a.getB(/* */).setSomeString(/* some string */);
}
Когда метод вернется, я ожидаю, что измененная сущность B будет обновлена (SQL UPDATE). По какой-то причине этого не происходит. Я подозреваю, что фреймворк знает только о добавлении / удалении в коллекцию bs
, но, поскольку каждый экземпляр в коллекции должен быть управляемым объектом, фреймворк должен знать об изменениях.
Не уверен, что мне здесь не хватает.
EDIT
Я создал хранилище для воспроизведения проблемы:
https://github.com/mikomarrache/hibernate-spring-issue
Если вы комментируете строки 25-27 класса MyServiceImpl
, выполняется сохранение в строке 22. Однако, если вы раскомментируете эти строки, похоже, что сохранение в строке 22 игнорируется, но второе сохранение в строке 27 выполнено, и, конечно, оно нарушает уникальное ограничение на имя. Для тестирования просто запустите модульный тест. Нет необходимости заполнять базу данных, на пути к классам есть сценарий SQL, который выполняется при запуске.