Как проверить, есть ли ссылка на объект перед удалением - PullRequest
11 голосов
/ 29 ноября 2011

У меня есть Java-приложение с веб-интерфейсом (Spring MVC), использующее Hibernate.У меня есть довольно простая схема БД с сущностью Group , которую вы можете добавить / удалить на одной веб-странице.Тогда есть еще один Сущность , имеющая Группа в качестве поля для этого Сущность имеет FK для Группа .Обратите внимание, что, как правило, существует много других объектов, ссылающихся на мою Group .

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

Есть ли способ выполнить проверку, на которую ссылается моя Группа , и удаление завершится неудачей, а не выполнением удаления и перехватом исключения?Какова лучшая практика здесь?

Спасибо

ПРИМЕЧАНИЕ : Просто чтобы быть понятным, простой выбор не является решением, поскольку Group может бытьна которые ссылаются, как правило, многие другие таблицы, а не только одна.

Ответы [ 3 ]

7 голосов
/ 29 ноября 2011

Проверка перед удалением менее эффективна и может привести к нарушению ограничения, если какая-либо ссылка добавляется другой транзакцией между моментом проверки и моментом удаления.

С другой стороны, он позволяет отображать более конкретное сообщение об ошибке пользователю (например, «на группу все еще ссылается FooBar»).

Просто делай то, что тебе кажется лучшим в твоем конкретном случае. Однако обратите внимание, что в случае возникновения какого-либо исключения вся транзакция должна быть откатана, а сеанс должен быть закрыт, поскольку такое исключение оставляет сеанс в несогласованном состоянии. Более того, это не удаление, а сброс или фиксация, которая вызовет исключение.

Теперь, если вы хотите проверить, волшебного решения не существует. У вас могут быть двунаправленные ассоциации, и вы можете проверить, что group.getUsers() является emtpy (хотя это приведет к получению всех пользователей группы). Или вы можете выполнить специальные запросы, такие как select count(user.id) from User user where user.group = :group, чтобы узнать, есть ли ссылка на группу. Но вам нужно сделать один из них для каждой возможной ссылки на группу.

0 голосов
/ 29 ноября 2011

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

0 голосов
/ 29 ноября 2011

Вы можете выполнить SELECT COUNT для сущности на основе идентификатора группы, а затем попытаться удалить группу только в том случае, если возвращенное значение равно 0.

Что плохого в том, чтобы окружить удаление с помощью try / catch?

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