Как пакетное удаление с помощью bulkUpdate - PullRequest
7 голосов
/ 09 апреля 2009

У меня есть общие настройки User / Role с таблицей соединений user_role. Я пытаюсь использовать Spring HibernateTemplate для массового удаления всех заблокированных пользователей, как это:

getHibernateTemplate().bulkUpdate("delete from User where locked=?", true);

Если удаляемый пользователь не имеет никаких ролей (нет записи в таблице user_role), то все идет хорошо; Однако, если у пользователя есть запись роли, я получаю следующую ошибку:

нарушение целостности нарушено - ребенок найдена запись

Роли определены в User.java следующим образом:

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "user_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<Role>();

Так, как я могу пакетно удалить пользователей, даже если у пользователя есть дочерние записи? Спасибо!

Ответы [ 4 ]

8 голосов
/ 22 июля 2010

Операции массового удаления не каскадируются к связанным объектам согласно спецификации JPA:

4.10 Операции массового обновления и удаления

Операции массового обновления и удаления применяются к объектам одного лица класс (вместе с его подклассами, если есть) Только одна сущность абстрактная Тип схемы может быть указан в Предложение FROM или UPDATE.

...

Операция удаления применяется только к сущности указанного класса и его подклассы. Это не каскад связанным лицам .

Однако я ожидаю, что провайдер JPA будет иметь дело с таблицами соединений. К сожалению, Hibernate нет, и это зарегистрировано в HHH-1917 . Боюсь, вам придется прибегнуть к нативному SQL, чтобы самостоятельно очистить таблицу соединений или использовать в схеме каскадные внешние ключи.

2 голосов
/ 09 апреля 2009

Каскадирование на уровне приложения (каскадирование через аннотации гибернации или аннотации JPA) работает только в том случае, если фактическая сущность фактически загружена из БД. Когда вы используете шаблон hibernate с HQL, вы заметите, что сущности не загружены, и HQL напрямую преобразуется в SQL для выполнения.

Если вы хотите групповое удаление, вы должны использовать HQL-запрос для удаления всех соответствующих таблиц (т.е. ролей) перед удалением данных родительской таблицы.

0 голосов
/ 29 июня 2011

Так как вы хотите массово удалить что-то, что имеет элементы, связанные с ManyToMany, вы должны сначала удалить отношение (в таблице соединений) или выполнить цикл, и для каждого элемента удалить вручную (безумно и слишком тяжело).

Итак, поскольку JPQL не позволяет это сделать, возможный способ - сделать собственный SQL-запрос для удаления нужного идентификатора в связанной таблице, а затем выполнить массовое удаление.

0 голосов
/ 09 апреля 2009

Я не совсем уверен, потому что мне трудно воссоздать эту проблему, но я думаю, что вам может понадобиться добавить каскад к вашему @ ManyToMany

@ManyToMany(cascade = CascadeType.ALL)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...