Hibernate не добавляет «каскад удаления» - PullRequest
1 голос
/ 08 декабря 2011

Использование cascade = CascadeType.REMOVE hibernate не добавляет 'ON DELETE CASCADE' во время генерации таблицы. Это правильное поведение? Нет проблем, если я выполняю em.remove () для родительского объекта, но возникает ошибка при попытке выполнить массовое удаление с помощью HQL.

PostgreSQL 9.1, Hibernate 4.0.0.CR7

Ответы [ 3 ]

7 голосов
/ 08 декабря 2011

Что вам нужно, так это аннотация @OnDelete, которая влияет на генерацию схемы в спящем режиме (операторы DDL).Однако эта аннотация не каскадно удаляет ссылки на сущности / строки в случае массового удаления, когда в определении внешнего ключа в базе данных нет предложения ON DELETE CASCADE.

@OneToMany
@OnDelete(action=OnDeleteAction.CASCADE)
public Set<Stuff> getStuff() {
  return stuff;
}
2 голосов
/ 08 декабря 2011

Это ожидаемое поведение. Каскадная аннотация говорит Hibernate каскадировать удаление, и ответственность за это лежит на Hibernate, а не на базе данных.

Запросы массового удаления полностью обходят сессию и аннотации каскадных объектов. Когда вы решите использовать их, вы должны обрабатывать каскад удаляет себя.

1 голос
/ 08 декабря 2011

Насколько я понимаю, функция «ON DELETE CASCADE», на которую вы ссылаетесь, является триггером базы данных. Hibernate не настраивает триггеры. Используя аннотации, Hibernate будет управлять удалением дочерних объектов, используя стандартные операторы SELECT и DELETE. Если вы включите отладку, вы увидите, что это происходит. Когда вы впервые начинаете использовать hibernate, это выглядит пугающе неэффективно, поэтому именно тогда вы и захотите использовать массовое удаление через HQL, на которое вы ссылаетесь.

Таким образом, создание таблиц не добавит специфические функции базы данных, такие как триггеры. Если вы хотите иметь возможность удалять дочерние объекты, попробуйте что-то подобное в зависимости от ваших требований

@OneToMany(cascade={CascadeType.ALL}, orphanRemoval=true)
private List<Case> cases = new ArrayList<Case>();

При непосредственном использовании HQL он обходит каскадную логику, поэтому вам может потребоваться написать собственный код «очистки», который периодически запускается для очистки orhapns и т. Д. Для эффективности я решил написать для этой цели хранимую процедуру.

Альтернативой является извлечение коллекции родительских объектов, которые вы хотите удалить, и просмотр их по одному. Если ваша коллекция большая, это неэффективно, но, по крайней мере, будет каскадным, как вы определили в аннотации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...