JPA 2.0/Hibernate и orphanRemoval: простая замена объекта не удаляет старый

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

Первая моя установка:

  • Весна 3.0.5.РЕЛИЗ
  • SprnigData JPA 1.0.1.РЕЛИЗ
  • Спящий режим 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, сохранив «пользователя», а затем установите новый AvatarImage «theNewAvatarImage», снова сохранив пользователя.

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

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

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

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

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

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

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


person It's Leto    schedule 22.09.2011    source источник


Ответы (2)


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

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

person Vineet Reynolds    schedule 22.09.2011

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

person Arash    schedule 13.03.2013