#java #hibernate #constraints #persistence #one-to-many
#java #спящий режим #ограничения #сохранение #один ко многим
Вопрос:
У меня проблема с hybernate, у меня есть 2 таких класса :
public Class Race {
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="race", orphanRemoval = true)
private List<Lap> laps = new ArrayList<>(0);
...
}
public Class Lap {
@ManyToOne(fetch = FetchType.LAZY, cascade=CascadeType.REFRESH)
@JoinColumn(name = "RACE_ID", nullable = false)
private Race race;
@OneToOne(mappedBy = "nextLap", fetch = FetchType.LAZY)
private Lap previousLap;
@OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "NEXT_ID")
private Lap nextLap;
...
}
В моей базе данных у меня также есть уникальное ограничение с NEXT_ID и RACE_ID
Моя проблема в том, что я хочу удалить свою расу с
txn = session.getTransaction();
txn.begin();
race = session.merge(race);
session.remove(race);
session.flush(); //=>Exception here
txn.commit();
Я получаю результат:
javax.постоянство.Исключение PersistenceException: org.hibernate.exception.Исключение ConstraintViolationException: не удалось выполнить пакет в org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154) в org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181) в org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188) в org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1364) в org.hibernate.internal.SessionImpl.flush(SessionImpl.java: 1347) в пакете.DAORace.deleteRace(DAORace.java:122)
Вызвано: java.sql.BatchUpdateException: ORA-00001: нарушено уникальное ограничение (LAP_UK1)
Спящий режим выполняет обновление на моем колене, когда я удаляю гонку, и мои ограничения нарушаются. Мой вопрос в том, как правильно удалять дочерние элементы без обновления, когда я удаляю родительский элемент?
Примечание: Если у меня есть только один дочерний элемент, я могу удалить его без каких-либо исключений, если у меня есть 2 или более дочерних элементов, у меня есть исключение.
Спасибо за вашу помощь!
Ответ №1:
Для удаления объектов в виде каскада наилучшим подходом является их удаление с помощью нескольких запросов.
Например:
em.createQuery("delete from Lap p where p.race.id = :id).setParameter("id", id).executeUpdate();
em.createQuery("delete from Race r where r.id = :id).setParameter("id", id).executeUpdate();
https://thorben-janssen.com/avoid-cascadetype-delete-many-assocations / читайте здесь для лучшего понимания.
Комментарии:
1. Спасибо за ваш ответ, я думаю, что это сработает, но на самом деле у меня есть много объектов под моим объектом Lap для удаления в виде каскада (но без уникального ограничения) Написание запросов будет немного утомительным и опасным, если я забыл объект для удаления, я думаю, что hibernate мог бы сделатьэто правильно