В системе, в которой я сейчас работает, есть политика, в которой объекты, не имеющие отношения, могут быть свободно удалены, а те, которые должны быть выполнены, должны быть логически удалены. Это предназначено для предотвращения удаления исторической информации.Hibernate: проверить нарушение ограничения внешнего ключа перед удалением?
Так что в основном то, что я пытался сделать, это определить, присутствует ли в данный момент ключ объекта в другой таблице. Если это не так, я бы просто вызвал delete(), иначе я бы установил свойство, которое указывает на логическое удаление, и вызовет update().
Я использую управление транзакциями Spring, поэтому я стараюсь как можно меньше связываться с сеансом. Мой первоначальный подход, казалось, работал на первом, но вы увидите, что она имеет большой недостаток:
@Transactional
public void deleteObject(SomeEntity object)
{
//try to delete
this.someEntityDAO.delete(object);
try //force foreign key constraint check
{
this.someEntityDAO.flush();
}
catch (ConstraintViolationException e)
{
//reload object
object= this.someEntityDAO.loadById(object.getId());
//save as inactive instead of deleting
object.setActive(false);
this.someEntityDAO.update(object);
}
}
Поскольку Hibernate исключение является фатальным, это совершенно ненадежно (даже если он работает). Мне было интересно, есть ли способ сделать какую-то операцию «peek», в которой я мог бы проверить, не удастся ли удалить из-за ограничения, фактически не выполнив операцию (и тем самым аннулирует сеанс). Единственное, о чем я могу думать, это вручную проверить каждую связанную таблицу, чтобы увидеть, присутствует ли идентификатор, но это было бы очень утомительно и подвержено ошибкам в таблицах со многими отношениями. Я хочу использовать ограничения, которые уже существуют в базе данных, если это возможно.
Да, я могу сделать это с помощью SQl напрямую или добавить дополнительный код Hibernate для проверки этих ограничений перед удалением.Дело в том, что я не хотел так поступать, так как тогда мне пришлось бы отслеживать все отношения между сущностями и вернуться к коду, если бы было добавлено больше отношений и т. Д. Если бы я был в порядке для этого, как я и предложил, мне просто нужно было бы правильно установить ограничения в БД и никогда не вернуться к этому коду еще раз, независимо от того, изменилась ли база данных в какой-то момент или нет. – JayPea
@JayPea «Если бы у меня был способ сделать это, как я предложил, мне просто нужно было бы правильно установить ограничения на БД и никогда не вернуться к этому коду еще раз, независимо от того, изменилась ли база данных в какой-то момент или нет. " Предполагая, что вы НЕ означает, что изменится база данных DESIGN, тогда ДА, вы МОЖЕТЕ это сделать! И должен. ... Референтная целостность - вещь VITAL; научиться этому, использовать его, позволить ему расширить свою работу! (BTW, я работаю с Postgres, Informix, Ingres, Oracle, DB2, Sybase, среди прочих - все серьезные реляционные системы баз данных имеют встроенные функции). –