JPA 2.0 / Hibernate and “orphanRemoval”: Just repl

2019-02-06 06:37发布

问题:

I have question regarding JPA 2.0, Hibernate and "orphanRemoval".

First my setup:

  • Spring 3.0.5.RELEASE
  • SprnigData JPA 1.0.1.RELEASE
  • Hibernate 3.5.2-Final
  • DBMS: PostgreSQL 9.0

I have two rather simple entity classes, "User" and "AvatarImage", A "User" has an "AvatarImage", and so between "User" and "AvatarImage" there is the relationship.

In the class "User", the property looks like this:

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

So that means, if the "avatarImage" property gets set to null, the reference between "User" and "AvatarImage" is removed and "orphanRemoval" mechanism will delete the "avatarImage" from the database (please correct me if I'm wrong).

So when I update the "avatarImage" for a certain user, I currently have to write this:

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

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

So setting the "avatarImage" property first to null, saving the "user", and then set the new AvatarImage "theNewAvatarImage", again saving the user.

This is the only way it currently works for me - the "orphanRemoval" will delete the old "avatarImage" on setting it to "null" and then saving the user.

But, I would have thought that this code should also work:

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

So I omit setting the "avatarImage" to "null" but just setting "theNewAvatarImage", replacing the old "avatarImage". But this does not work, the old AvatarImage does not get removed from the database upon transaction commit.

Does anyone know, why the second code (just replacing the AvatarImage without setting it to "null" before) does not work?

I really appreciate any help you can offer

Thanks a lot!

回答1:

This is related to Hibernate JIRA tickets HHH-5559 and HHH-6484. By and large, Hibernate, as of today, requires you to set the reference to null and flush the persistence context, before providing a new value to the relationship (see the test case in HHH-6484); it is only in such a case that Hibernate issues a SQL DELETE statement, providing a broken implementation (IMHO) for orphanRemoval.

In short, you'll need to wait for the bugs to be fixed, or write code to nullify references and flush the persistence context, or use a JPA provider that supports orphanRemoval in this manner (EclipseLink 2.3.0 does).



回答2:

As of @OneToMany relationship, this is related to Hibernate JIRA ticket HHH-6709. Please vote for these so it get some attention.