2016-01-17 2 views
2

Существует сущность A, связывающая (многозначно) сущность B с обратным (отображаемым) ссылкой от B до A. Также существует ссылка A-C и обратная ссылка C на A. Когда я выдаю entityManager.remove (A), затем flush(), «delete» не gerenated! Но и исключений нет. Это так же, как и remove(). Почему это произойдет? Если перед remove() мы извлекаем A из обратных ссылок B.listOfA и C.listOfA, «delete» генерируется, как ожидалось.Безмолвно игнорируется remove()

Также примечание my another question, где я пришел к выводу, что orphanRemoval не всегда работает должным образом. Теперь я начинаю подозревать, что, возможно, каскадирование сработало хорошо, но после этого фактическое каскадное удаление было «проглочено», как я описал здесь.

+0

Проведение сопоставления объектов вместе с вашей логикой удаления поможет. Вы можете проверить, начинаете ли вы и совершаете транзакцию в менеджере сущностей. –

+1

Удаление сирот должно осуществляться только лицами, находящимися в частной собственности. Если у вашего «сироты» есть другие отношения с ним, эти отношения должны быть отменены - то, что JPA не сделает для вас. Если в любом из этих отношений есть каскадные настройки, они могут вызвать такие проблемы. Удаление объектов, на которые ссылаются другие, без исправления этих ссылок, вызывает всевозможные проблемы при работе с кэшированием JPA. – Chris

ответ

2

Посмотрите на это answer. В принципе, спецификация JPA требует, чтобы удаленный объект снова управлялся, если к нему применяется операция persist.

Чтобы убедиться, что это действительно происходит, включите уровень журнала трассировки для org.hibernate пакета и поиск записей журнала, как:

un-scheduling entity deletion ... 

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

+1

Тогда вы должны сказать, что A был запланирован для удаления, но затем JPA пересмотрен, потому что я снова вызвал em.persist (A). Но я не вызываю persist() вообще! Единственное, что я сделал, это em.remove (A), за которым следует em.flush(). Или вы имели в виду, что persist (B) и persist (C) происходят в любом случае, потому что remove (A) каким-то образом касается B и C (хотя я не изменял их явно)? Хорошо, я проверю это. –

+1

@MaksimGumerov. В момент кратковременного обновления операция persist выполняется каскадом для всех ассоциаций со всех объектов, присутствующих в контексте персистентности. –