В системе, над которой я сейчас работаю, есть политика, в которой объекты, не имеющие отношений, могут быть свободно удалены, а те, которые имеют, должны быть удалены логически. Это сделано для предотвращения удаления исторической информации.
Итак, в основном я пытался определить, присутствует ли ключ объекта в другой таблице. Если это не так, я бы просто вызвал 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» операции, в которой я мог бы проверить, не удалится ли удаление из-за ограничения, без фактического выполнения операции (и, таким образом, аннулирования сеанса). Единственное, о чем я могу подумать, - это вручную проверить каждую связанную таблицу, чтобы увидеть, присутствует ли идентификатор, но это будет очень утомительно и подвержено ошибкам в таблицах со многими взаимосвязями. Я хочу использовать ограничения, которые уже существуют в базе данных, если это возможно.