Still a way to unproxy an entity directly inside getter in Hibernate 5.2?

Viewed 421

We currently use Hibernate 5.1 in our application and we have lazy OnyToOne relations in a lot of places. Inside the getter method, we un-proxy the entities so that the caller/client does not have to care about unproxying the object itself. It's, in fact, a very nice solution because unproxying is done in a central place and there is no risk that the caller forgets to unproxy. The caller often does an instanceof on the entity or calls .getClass() meaning that it must be unproxied to work.

This is how such a getter looks like:

@OneToOne(cascade=CascadeType.ALL, orphanRemoval=true, fetch=FetchType.LAZY)
@JoinColumn(name="ContractAgreementId")
public ContractAgreement getContractAgreement() {
    return ORMUtils.initializeAndUnproxy(contractArgreement);
}

The initializeAndUnproxy() method is basically doing this:

Hibernate.initialize(entity);
return (T)((HibernateProxy)entity).getHibernateLazyInitializer().getImplementation();

This was working perfectly until Hibernate 5.1, but when we tried to upgrade to 5.2 we found out it behaves a bit different than before. If a cascade type ALL is used like in the example above, Hibernate tries to delete the related entity (contractArgreement in the example above) at the end of the session although there is absolutely no update done on the entity (simply loading the parent entity from the entity manager is enough to run into that problem). My guess is that this is done because Hibernate does not find the same object (his proxy) when calling the getter but instead finds a different one (the unproxied object). So it thinks the object must be deleted from the database. I hope you know what I mean. Hibernate thinks the relation was updated (replaced by a different object) which in fact is not the case; it was just unproxied.

My question is, is this an intentional behavior in Hibernate 5.2 or should Hibernate (like in 5.1 or earlier) recognize that the object doesn't have changed when it discovers the unproxied object instead of the proxy? And if this is intentional behavior, is there a different way of doing the unproxying inside the getter without running into that problem?

0 Answers
Related