JPA 2.0 / Hibernate и "orphanRemoval": просто замена объекта не удаляет старый - PullRequest
15 голосов
/ 22 сентября 2011

У меня есть вопрос относительно JPA 2.0, Hibernate и "orphanRemoval".

Первые мои настройки:

  • Spring 3.0.5.RELEASE
  • SprnigData JPA 1.0.1.RELEASE
  • Hibernate 3.5.2-Final
  • СУБД: PostgreSQL 9.0

У меня есть два довольно простых класса сущностей: «Пользователь» и «AvatarImage», «Пользователь» имеет «AvatarImage», и поэтому между «Пользователем» и «AvatarImage» существует связь.

В классе «Пользователь» свойство выглядит следующим образом:

// class "User"
@OneToOne(cascade = CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval = true)
private AvatarImage    avatarImage;

Таким образом, это означает, что если для свойства "avatarImage" установлено значение null, ссылка между "User" и "AvatarImage" удаляется, и механизм "orphanRemoval" удалит "avatarImage" из базы данных (пожалуйста, исправьте меня, еслиЯ не прав).

Поэтому, когда я обновляю "avatarImage" для определенного пользователя, мне в настоящее время приходится писать следующее:

user.setAvatarImage( null );  // First set it to null
userRepository.save( user );  // Now "orphanRemoval" will delete the old one

user.setAvatarImage( theNewAvatarImage );
userRepository.save( user );

Поэтому сначала установите свойство "avatarImage"null, сохраняя "user", а затем установите новый AvatarImage "theNewAvatarImage", снова сохранитеing user.

Это единственный способ, которым он в настоящее время работает для меня - «orphanRemoval» удалит старый «avatarImage», установив его в «null», а затем сохранит пользователя.

Но я бы подумал, что этот код также должен работать:

user.setAvatarImage( theNewAvatarImage );
userRepository.save( user );

Поэтому я опускаю установку «avatarImage» на «null», а просто установку «theNewAvatarImage», заменяя старый «avatarImage».Но это не работает, старый AvatarImage не удаляется из базы данных при фиксации транзакции.

Кто-нибудь знает, почему второй код (просто заменяющий AvatarImage без установки его в «null» раньше) не работает?работа?

Я очень ценю любую помощь, которую вы можете предложить

Спасибо большое!

Ответы [ 2 ]

12 голосов
/ 22 сентября 2011

Это относится к билетам Hibernate JIRA HHH-5559 и HHH-6484 . По большому счету, Hibernate на сегодняшний день требует, чтобы вы установили ссылку на ноль и очистили контекст постоянства, прежде чем предоставить новое значение для отношения (см. Контрольный пример в HHH-6484); только в таком случае Hibernate выдает оператор SQL DELETE, предоставляя некорректную реализацию (IMHO) для orphanRemoval.

Короче говоря, вам нужно подождать, пока ошибки будут исправлены, или написать код, чтобы аннулировать ссылки и очистить контекст постоянства, или использовать JPA-провайдер, который поддерживает orphanRemoval таким образом (EclipseLink 2.3.0 делает ).

1 голос
/ 13 марта 2013

Начиная с отношения @OneToMany, это связано с билетом Hibernate JIRA HHH-6709 Пожалуйста, проголосуйте за них, чтобы привлечь к себе внимание.

...