2015-01-13 3 views
0

Рассмотрите объект Team, который имеет коллекцию Players. Картинка Team позволяет каскадным слияниям и сохранять обновления до Players.Спящий режим: перемещение каскадного объекта с одного объекта на другой

У меня есть объект Team, который содержит 4 Players в базе данных.

Моя служба позволяет пользователю указать Team и Player, а затем выполните следующие действия:

  1. Создает клон B существующего Team
  2. Удаляет Player C из A и добавляет его в коллекцию в Team B

Все перечисленное сделано в одной транзакции, которая выполняет только запросы к базе данных. Он не выполняет обновления.

Вторая транзакция используется для сохранения объектов в базе данных. Однако я не уверен, как подойти к этому.

Моя существующая логика содержит следующее:

  1. Merge Team B, который будет эффективно сохранить команды B, а затем объединить в Player C. Player номер версии языка C инкрементируется
  2. Merge Team A. Однако это сбой, поскольку сеанс Hibernate Team Экземпляр все еще имеет ссылку на старый номер версии Player C.

Как мне сэкономить эти 2 сущности? Должен ли я сохранять Player C отдельно и избегать использования каскадов?

ответ

0

Операция слияния не должна быть вашей операционной системой, когда дело доходит до хранения вещей. Он используется для объединения отдельного объекта обратно с entitymanager. Очень короткое повторение различных состояний объекта может быть с JPA (вы, возможно, придется прочитать об этом):

  • Transient: Новый объект, который еще не был сохранен в базе данных (и, таким образом, неизвестно entitymanager.) Не имеет идентификатора.
  • Управляемый: объект, который отслеживает сущ. Управляемые объекты - это то, с чем вы работаете в рамках транзакции, и все изменения, сделанные для управляемого объекта, будут автоматически сохранены после совершения транзакции.
  • Отдельно: ранее управляемый объект, который все еще доступен после того, как выполняется трансмиссия. (Управляемый объект за пределами транзакции.) Имеет идентификатор.

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

Для хранения объекта в базе данных метод отличается в соответствии с состоянием объекта.

  • Преходящий: EntityManager.persist.Это сохранит объект, а также сделает его управляемым объектом.
  • Управляемый: ничего. Управляемый объект обновляется после завершения транзакции.
  • Индивидуальный: EntityManager.merge. Поскольку entitymanager больше не распознает объект, вам необходимо его повторно ввести. Остерегайтесь, хотя, поскольку persist-method делает объект, который вы передаете ему, управляется, метод merge не делает этого. Вместо этого он возвращает управляемую копию объекта.

Итак, с этой основой давайте посмотрим, что вы здесь делаете.

Сначала вы загружаете объект из EntityManager. Учитывая, что вы делаете это в контексте транзакции, этот объект находится в данный момент. Затем вы копируете объект, создавая новый, переходный объект. Затем вы вносите некоторые изменения в оба объекта.

Далее сделка совершена. Затем ваш управляемый объект будет обновлен, а ваш переходный режим останется временным. Затем управляемый объект переживает транзакцию, становясь отсоединенной. Затем вы сохраняете свой переходный объект, здесь вы должны использовать метод persist, а не метод слияния. Во всяком случае, чтобы обновить отдельный объект (который уже должен быть обновлен), вам нужно передать его методу слияния.

Итак, чтобы получить правильную каскадную форму Team to Player, вам нужно будет добавить как persist, так и merge как каскадные операции.

Кроме того, при создании клонированного объекта убедитесь, что вы не копируете идентификатор, так как это сделает его таким же, как старый, который может сказать любой Hibernate.

Если игрок C в команде A и игрок C в команде B имеет другой номер версии, он не может быть одним и тем же объектом. Возможно, что-то происходит, когда вы отсоединяете объекты, приводя к тому, что игрок C в обеих командах не является одним и тем же объектом (но не уверен в этом ..)

Смежные вопросы