Я действительно никогда не понимал этого поведения в спящем режиме. Я использую отношения @OneToMany в Entity, называемом "Parent", который аннотируется следующим образом:
@OneToMany(cascade = {CascadeType.ALL, CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE }, orphanRemoval = true)
@JoinColumn(name = "entity_id", insertable = true, updatable = true, nullable = false)
private List<Child> children;
Теперь я хочу сделать следующее за одну транзакцию:
- Получить родительский объект
- итерация по списку детей
- удалить один из дочерних элементов
- добавить новый
Итак, в основном я просто полностью заменяю одного из детей.
Насколько я понимаю эту проблему, я должен был бы сделать что-то вроде этого: (обратите внимание, что это просто некоторый псевдокод java, чтобы проиллюстрировать проблему)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void deleteAndAdd(Long parentId, Long childId) {
Parent parent = entityManager.find(parentId);
for (Iterator it = parent.children.iterator(); it.hasNext();) {
Child child = it.next();
if (child.id == childId) {
it.remove();
}
}
Child newChild = new Child();
parent.children.add(newChild);
}
Однако это не удается, если новый Child имеет те же уникальные ключевые значения, что и старый. Таким образом, в основном кажется, что старый дочерний объект не удаляется должным образом, прежде чем новый сохраняется.
Если я добавлю entityManager.flush() между удалением старого дочернего элемента и сохранением нового дочернего элемента следующим образом:
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void deleteAndAdd(Long parentId, Long childId) {
Parent parent = entityManager.find(parentId);
for (Iterator it = parent.children.iterator(); it.hasNext();) {
Child child = it.next();
if (child.id == childId) {
it.remove();
}
}
entityManager.flush();
Child newChild = new Child();
parent.children.add(newChild);
}
Все работает отлично. Ребенок удаляется до того, как будет вставлен новый.
Поскольку я не хочу, чтобы этот спящий режим смешивал порядок операторов, отправленных в БД, должно быть что-то еще, что я предполагаю о спящем режиме, что не так. Любые идеи, почему последний пример работает, а первый - нет?
Спящий режим версии 3.5. DB - Mysql InnoDB