HHH-9071 - Proxy narrowing loses the initialized state of the original proxy

This commit is contained in:
Steve Ebersole 2014-03-21 09:59:04 -05:00
parent 2cf52cc7f1
commit c5bdec20b9
2 changed files with 24 additions and 26 deletions

View File

@ -624,42 +624,39 @@ public class StatefulPersistenceContext implements PersistenceContext {
throws HibernateException {
final Class concreteProxyClass = persister.getConcreteProxyClass();
final boolean alreadyNarrow = concreteProxyClass.isAssignableFrom( proxy.getClass() );
final boolean alreadyNarrow = concreteProxyClass.isInstance( proxy );
if ( !alreadyNarrow ) {
LOG.narrowingProxy( concreteProxyClass );
// If an impl is passed, there is really no point in creating a proxy.
// It would just be extra processing. Just return the impl
if ( object != null ) {
proxiesByKey.remove( key );
//return the proxied object
return object;
}
else {
proxy = persister.createProxy( key.getIdentifier(), session );
//overwrite old proxy
final Object proxyOrig = proxiesByKey.put( key, proxy );
if ( proxyOrig != null ) {
if ( ! ( proxyOrig instanceof HibernateProxy ) ) {
throw new AssertionFailure(
"proxy not of type HibernateProxy; it is " + proxyOrig.getClass()
);
// Similarly, if the original HibernateProxy is initialized, there
// is again no point in creating a proxy. Just return the impl
final HibernateProxy originalHibernateProxy = (HibernateProxy) proxy;
if ( !originalHibernateProxy.getHibernateLazyInitializer().isUninitialized() ) {
final Object impl = originalHibernateProxy.getHibernateLazyInitializer().getImplementation();
// can we return it?
if ( concreteProxyClass.isInstance( impl ) ) {
proxiesByKey.remove( key );
return impl;
}
}
HibernateProxy originalHibernateProxy = (HibernateProxy) proxyOrig;
HibernateProxy newHibernateProxy = (HibernateProxy) proxy;
// Otherwise, create the narrowed proxy
final HibernateProxy narrowedProxy = (HibernateProxy) persister.createProxy( key.getIdentifier(), session );
// set the read-only/modifiable mode in the new proxy to what it was in the original proxy
final boolean readOnlyOrig = originalHibernateProxy.getHibernateLazyInitializer().isReadOnly();
newHibernateProxy.getHibernateLazyInitializer().setReadOnly( readOnlyOrig );
narrowedProxy.getHibernateLazyInitializer().setReadOnly( readOnlyOrig );
// if the original proxy is already initialized, initialize the new proxy
if ( !originalHibernateProxy.getHibernateLazyInitializer().isUninitialized() ) {
newHibernateProxy.getHibernateLazyInitializer().setImplementation(
originalHibernateProxy.getHibernateLazyInitializer().getImplementation() );
}
}
return proxy;
}
return narrowedProxy;
}
else {

View File

@ -80,7 +80,8 @@ public class ProxyNarrowingTest extends BaseCoreFunctionalTestCase {
ConcreteEntity concreteEntityProxy = (ConcreteEntity) session.load( ConcreteEntity.class, abstractEntityProxy.getId() );
// the new proxy created should be initialized
assertTrue( ( concreteEntityProxy instanceof HibernateProxy ) && Hibernate.isInitialized( concreteEntityProxy ) );
assertTrue( Hibernate.isInitialized( concreteEntityProxy ) );
assertTrue( session.contains( concreteEntityProxy ) );
}
finally {
session.close();