JPA 2.0 / Hibernate and "orphanRemoval": Just replacing an entity does not remove the old one
I have question regarding JPA 2.0, Hibernate and "orphanRemoval".
First my setup:
- Spring 3.0.5.RELEASE
- SprnigData JPA 1.0.1.RELEASE
- Hiberna开发者_运维知识库te 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!
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).
As of @OneToMany relationship, this is related to Hibernate JIRA ticket HHH-6709. Please vote for these so it get some attention.
精彩评论