похоже, слияние в спящем режиме не предназначалось для связывания временных объектов с постоянными
Слияние является стандартом JPA - объединяет «новые и отдельные экземпляры объекта» с «экземплярами управляемого объекта (контекст сохраняемости)». Будет каскадироваться между отношениями FK, помеченными Cascade.MERGE или Cascade.ALL.
С точки зрения JPA — нет, слияние не предназначалось для связывания ваших потоковых временных объектов Xstream с постоянными. JPA предназначен для слияния, чтобы работать с обычным жизненным циклом JPA - создавать новые объекты, сохранять их, получать/находить их, отсоединять их, изменять их (включая добавление новых объектов), объединять их, при необходимости изменять их еще немного, затем сохранять/сохранять их . Это преднамеренный дизайн, так что JPA оптимизирован и эффективен - каждому отдельному объекту, сохраняемому в базе данных, не нужно предшествовать поиск состояния объекта, чтобы определить, нужно ли/что вставлять/обновлять. Состояние объекта контекста персистентности JPA уже содержит достаточно подробностей, чтобы определить это.
Ваша проблема в том, что у вас есть новые экземпляры сущностей, которые вы хотите вести как если бы они были отсоединены, а это не способ JPA.
SaveOrUpdate — это проприетарная операция гибернации: если у объекта есть идентификатор, он обновляется, но если у него нет объекта, он вставляется.
С точки зрения hibernate - да, слияние с последующим saveOrUpdate теоретически может работать для связывания (потоковых Xstream) временных объектов с постоянными, но у него могут быть ограничения при использовании в сочетании с операциями JPA. saveOrUpdate ДЕЙСТВИТЕЛЬНО предшествует каждому объекту, сохраняемому в базе данных, с извлечением, чтобы определить, нужно ли/что вставлять/обновлять - это умно, но это не JPA и не самое производительное. то есть вы должны быть в состоянии заставить это работать с некоторой осторожностью и правильной конфигурацией - и использовать операции гибернации, а не операции JPA, когда возникает конфликт.
Я получаю сообщения об ошибках, например:
org.hibernate.ObjectDeletedException: удаленный объект будет повторно сохранен каскадно (удаление удаленного объекта из ассоциаций): [com.......SomeObject#353296]
Я считаю, что это может быть вызвано двумя факторами:
- где-то в вашем (созданном Xstream) графе объектов отсутствует экземпляр дочернего объекта, который присутствовал бы, если бы вы выполнили (каскадное) извлечение с использованием JPA: это дает удаление объекта
где-то еще в вашем (созданном Xstream) графе объектов присутствует эта же дочерняя сущность: это дает повторно сохраняемый объект
Как это отладить: (а) создать граф объектов из Xstream и распечатать его ПОЛНОСТЬЮ - каждый объект, каждое поле; (b) загрузите тот же граф объектов через JPA, каскадно извлеките из верхнего объекта и распечатайте его ПОЛНОСТЬЮ - каждый объект, каждое поле (c) сравните два - что-то отсутствует в (a), что присутствует в (b )??
Есть ли способ добиться того, что я хочу сделать, без необходимости получать постоянный объект в сеансе и изменять его вместо изменения временного объекта и пытаться сохранить его и переопределить существующий постоянный объект?
Надеюсь, с помощью только что предложенной отладки/исправления.
ИЛИ мое грубое предложение (глупо) обойти эту ошибку (хотя производительность немного замедляется): после того, как вы заполните идентификаторы в графе объектов, вызовите EntityManager.clear(), ЗАТЕМ продолжите слияние() и saveOrUpdate() . Но UNIT TEST результаты БД - чтобы убедиться, что вы не упустили что-то важное при заполнении вашего графика Xstream.
Для тестирования / в крайнем случае попробуйте saveOrUpdate() без merge(), но тогда вам может потребоваться очистить() менеджер Entity, чтобы избежать исключений Hibernate, таких как NonUniqueObjectException.
Дайте мне знать, если вы узнаете больше / получите больше информации B^)
person
Glen Best
schedule
18.03.2013