When Hibernate determines whether it should null out references to associated entities, it checks if the entity is wrapped in a proxy.
Code:
if ( object instanceof HibernateProxy ) {
// if its an uninitialized proxy it can't be transient
LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
if ( li.getImplementation(session) == null ) {
return false;
// ie. we never have to null out a reference to
// an uninitialized proxy
}
else {
//unwrap it
object = li.getImplementation();
}
}
In case the proxy has not been initialized, Hibernate decides there is no need to null out the reference. It does the check by calling
getImplementation(session) which checks if the entity is available in the current persistentContext. If that code succeeds, Hibernate decides to unwrap the proxy, but at that time it calls
getImplementation() without session, which tries to actually initialize the proxy. And that will fail if the proxy has been detached.
In my opinion, there should be no call to
getImplementation().
I suggest the following correction:
Code:
if ( object instanceof HibernateProxy ) {
// if its an uninitialized proxy it can't be transient
LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
//TODO fix: never call getImplementation() without session, since it would try to initialize the proxy
Object implementation = li.getImplementation(session);
if (implementation == null) {
return false;
// ie. we never have to null out a reference to
// an uninitialized proxy
}
else {
//unwrap it
object = implementation;
}
}