Using unproxy in getter does not work properly


Unproxying a lazyly loaded object in a getter method was never a problem up to version 5.1, but in 5.2 Hibernate somehow tries to delete an associated object (OneToOne) from the database although the association was never changed.

Please have a look at the test case I created, I think this should make it clear: (Test class JPAUnitTestCase)

Relevant code snippet:

Note: Hibernate.unproxy() was introduced in 5.2, the 5.1 (and prior) code of course looked like this:

I guess Hibernate expects the getter to return the proxy, but finds the unproxied object and concludes the association was altered (causing the deletion attempt of the child).
Hibernate should treat the proxy object and the unproxied object as the same object like in 5.1 or earlier so that the unproxying can still be done in the getter (which is very nice because it is a very central place and the caller does not have to care about unproxying).

Please clarify if this is a bug or if this behaviour was introduced intentionally.




Gail Badner
September 28, 2017, 7:11 PM

, I agree that the fix for should be reverted. I was more wondering what it was from that fix that changed this behavior and whether a more realistic use case could fail. If so, it would help a lot to understand why this is failing now.

What you suggest seems OK, I'm just trying to understand if this could happen in other cases.

Chris Cranford
September 29, 2017, 1:52 PM

The major part that altered this behavior comes from the introduction of the following if-block inside #cascadeLogicalOneToOneOrphanRemoval.

What this block did not account for was that after the #unproxyAndReassociate invocation that there could be a possibility that child and loadedValue may point to the same instance, in which case we should not trigger the orphan removal; hence the additional if-check I mentioned in a prior comment to satisfy this use case.

Beyond that, I cannot think of any other use case where this creates an issue. In fact, removing the above referenced if-block where we reassociate allows the user's test case to pass; however that does revert and break the fix we were accomplishing for HHH-9663. So I think the extra if-check to compare the reassociated loadedValue with child to abort the cascade delete-orphan is the best of both worlds and shouldn't create any other issue.

I'll send in my PR with this fix & the test and go from there.

Gail Badner
September 29, 2017, 6:13 PM

, sounds good.

Gail Badner
October 2, 2017, 8:09 PM

Fixed in master.

Marco Perazzo
October 6, 2017, 1:44 PM

Hey guys, thanks for the effort!


Chris Cranford


Marco Perazzo

Fix versions





Suitable for new contributors


Requires Release Note


Pull Request




Worked in



Affects versions