HHH-13633 : Bugs join-fetching a collection when scrolling with a stateless session using enhancement as proxy
(cherry picked from commit b589251166
)
This commit is contained in:
parent
e2a403e19d
commit
f1fa438bbe
|
@ -46,6 +46,7 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.query.spi.ScrollableResultsImplementor;
|
||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||
|
||||
|
@ -298,29 +299,62 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
|
|||
// caller did not request forceful eager loading, see if we can create
|
||||
// some form of proxy
|
||||
|
||||
final boolean allowBytecodeProxy = getFactory()
|
||||
.getSessionFactoryOptions()
|
||||
.isEnhancementAsProxyEnabled();
|
||||
|
||||
final boolean entityHasHibernateProxyFactory = persister.getEntityMetamodel()
|
||||
.getTuplizer()
|
||||
.getProxyFactory() != null;
|
||||
|
||||
// first, check to see if we can use "bytecode proxies"
|
||||
|
||||
final EntityMetamodel entityMetamodel = persister.getEntityMetamodel();
|
||||
final BytecodeEnhancementMetadata bytecodeEnhancementMetadata = entityMetamodel.getBytecodeEnhancementMetadata();
|
||||
if ( allowBytecodeProxy && bytecodeEnhancementMetadata.isEnhancedForLazyLoading() ) {
|
||||
|
||||
// we cannot use bytecode proxy for entities with subclasses
|
||||
if ( !entityMetamodel.hasSubclasses() ) {
|
||||
// if the entity defines a HibernateProxy factory, see if there is an
|
||||
// existing proxy associated with the PC - and if so, use it
|
||||
if ( entityHasHibernateProxyFactory ) {
|
||||
final PersistenceContext persistenceContext = getPersistenceContext();
|
||||
final Object proxy = persistenceContext.getProxy( entityKey );
|
||||
|
||||
if ( proxy != null ) {
|
||||
LOG.trace( "Entity proxy found in session cache" );
|
||||
|
||||
final LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
|
||||
if ( li.isUnwrap() ) {
|
||||
return li.getImplementation();
|
||||
}
|
||||
|
||||
return persistenceContext.narrowProxy( proxy, persister, entityKey, null );
|
||||
}
|
||||
|
||||
// specialized handling for entities with subclasses with a HibernateProxy factory
|
||||
if ( persister.getEntityMetamodel().hasSubclasses() ) {
|
||||
// entities with subclasses that define a ProxyFactory can create
|
||||
// a HibernateProxy.
|
||||
LOG.debugf( "Creating a HibernateProxy for to-one association with subclasses to honor laziness" );
|
||||
return createProxy( entityKey );
|
||||
}
|
||||
return bytecodeEnhancementMetadata.createEnhancedProxy( entityKey, false, this );
|
||||
}
|
||||
}
|
||||
|
||||
// we could not use bytecode proxy, check to see if we can use HibernateProxy
|
||||
if ( persister.hasProxy() ) {
|
||||
final PersistenceContext persistenceContext = getPersistenceContext();
|
||||
final Object existingProxy = persistenceContext.getProxy( entityKey );
|
||||
if ( existingProxy != null ) {
|
||||
return persistenceContext.narrowProxy( existingProxy, persister, entityKey, null );
|
||||
}
|
||||
else {
|
||||
final Object proxy = persister.createProxy( id, this );
|
||||
persistenceContext.addProxy( entityKey, proxy );
|
||||
return proxy;
|
||||
if ( !entityMetamodel.hasSubclasses() ) {
|
||||
return bytecodeEnhancementMetadata.createEnhancedProxy( entityKey, false, this );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( persister.hasProxy() ) {
|
||||
final PersistenceContext persistenceContext = getPersistenceContext();
|
||||
final Object existingProxy = persistenceContext.getProxy( entityKey );
|
||||
if ( existingProxy != null ) {
|
||||
return persistenceContext.narrowProxy( existingProxy, persister, entityKey, null );
|
||||
}
|
||||
else {
|
||||
return createProxy( entityKey );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -329,6 +363,12 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
|
|||
return get( entityName, id );
|
||||
}
|
||||
|
||||
private Object createProxy(EntityKey entityKey) {
|
||||
final Object proxy = entityKey.getPersister().createProxy( entityKey.getIdentifier(), this );
|
||||
getPersistenceContext().addProxy( entityKey, proxy );
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
Loading…
Reference in New Issue