HHH-8276 - Integrate LoadPlans into UniqueEntityLoader (PoC)

This commit is contained in:
Strong Liu 2013-08-15 00:00:33 +08:00 committed by Steve Ebersole
parent c5f3ddeccb
commit aaadcd74ee
5 changed files with 94 additions and 93 deletions

View File

@ -84,8 +84,6 @@ public class LoadPlanTreePrinter {
printWriter.flush(); printWriter.flush();
printStream.flush(); printStream.flush();
log.debug( new String( byteArrayOutputStream.toByteArray() ) ); log.debug( new String( byteArrayOutputStream.toByteArray() ) );
// log.debug( toString( loadPlan, aliasResolutionContext ) );
} }
private void logTree( private void logTree(

View File

@ -129,11 +129,11 @@ public class AliasResolutionContextImpl implements AliasResolutionContext {
} }
public CollectionReferenceAliases generateCollectionReferenceAliases(String uid, CollectionPersister persister) { public CollectionReferenceAliases generateCollectionReferenceAliases(String uid, CollectionPersister persister) {
final String manyToManyTableAlias = persister.isManyToMany()? createTableAlias( persister.getRole() ) : null;
final String tableAlias = createTableAlias( persister.getRole() );
final CollectionReferenceAliasesImpl aliases = new CollectionReferenceAliasesImpl( final CollectionReferenceAliasesImpl aliases = new CollectionReferenceAliasesImpl(
createTableAlias( persister.getRole() ), tableAlias,
persister.isManyToMany() manyToManyTableAlias,
? createTableAlias( persister.getRole() )
: null,
createCollectionAliases( persister ), createCollectionAliases( persister ),
createCollectionElementAliases( persister ) createCollectionElementAliases( persister )
); );
@ -212,7 +212,7 @@ public class AliasResolutionContextImpl implements AliasResolutionContext {
collectionReferenceAliasesMap = new HashMap<String, CollectionReferenceAliases>(); collectionReferenceAliasesMap = new HashMap<String, CollectionReferenceAliases>();
} }
collectionReferenceAliasesMap.put( querySpaceUid, collectionReferenceAliases ); collectionReferenceAliasesMap.put( querySpaceUid, collectionReferenceAliases );
registerSqlTableAliasMapping( querySpaceUid, collectionReferenceAliases.getElementTableAlias() ); registerSqlTableAliasMapping( querySpaceUid, collectionReferenceAliases.getCollectionTableAlias() );
} }
@Override @Override

View File

@ -68,7 +68,7 @@ import org.hibernate.sql.JoinType;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class LoadQueryJoinAndFetchProcessor { public class LoadQueryJoinAndFetchProcessor {
private static final Logger log = CoreLogging.logger( LoadQueryJoinAndFetchProcessor.class ); private static final Logger LOG = CoreLogging.logger( LoadQueryJoinAndFetchProcessor.class );
private final AliasResolutionContextImpl aliasResolutionContext; private final AliasResolutionContextImpl aliasResolutionContext;
private final QueryBuildingParameters buildingParameters; private final QueryBuildingParameters buildingParameters;
@ -91,6 +91,7 @@ public class LoadQueryJoinAndFetchProcessor {
} }
public void processQuerySpaceJoins(QuerySpace querySpace, SelectStatementBuilder selectStatementBuilder) { public void processQuerySpaceJoins(QuerySpace querySpace, SelectStatementBuilder selectStatementBuilder) {
LOG.debug( "processing queryspace " + querySpace.getUid() );
final JoinFragment joinFragment = factory.getDialect().createOuterJoinFragment(); final JoinFragment joinFragment = factory.getDialect().createOuterJoinFragment();
processQuerySpaceJoins( querySpace, joinFragment ); processQuerySpaceJoins( querySpace, joinFragment );
@ -127,7 +128,16 @@ public class LoadQueryJoinAndFetchProcessor {
else if ( EntityQuerySpace.class.isInstance( join.getRightHandSide() ) ) { else if ( EntityQuerySpace.class.isInstance( join.getRightHandSide() ) ) {
// do not render the entity join for a one-to-many association, since the collection join // do not render the entity join for a one-to-many association, since the collection join
// already joins to the associated entity table (see doc in renderCollectionJoin()). // already joins to the associated entity table (see doc in renderCollectionJoin()).
if ( join.getLeftHandSide().getDisposition() != QuerySpace.Disposition.COLLECTION || if ( join.getLeftHandSide().getDisposition() == QuerySpace.Disposition.COLLECTION &&
CollectionQuerySpace.class.cast( join.getLeftHandSide() ).getCollectionPersister().isManyToMany() ) {
final CollectionQuerySpace leftHandSide = (CollectionQuerySpace) join.getLeftHandSide();
final CollectionReferenceAliases aliases = aliasResolutionContext.resolveCollectionReferenceAliases(
leftHandSide.getUid()
);
renderManyToManyJoin(aliases, leftHandSide, join, joinFragment );
}
else if ( join.getLeftHandSide().getDisposition() != QuerySpace.Disposition.COLLECTION ||
! CollectionQuerySpace.class.cast( join.getLeftHandSide() ).getCollectionPersister().isOneToMany() ) { ! CollectionQuerySpace.class.cast( join.getLeftHandSide() ).getCollectionPersister().isOneToMany() ) {
renderEntityJoin( join, joinFragment ); renderEntityJoin( join, joinFragment );
} }
@ -371,34 +381,34 @@ public class LoadQueryJoinAndFetchProcessor {
); );
} }
// private void renderManyToManyJoin( private void renderManyToManyJoin(
// CollectionReferenceAliases aliases, CollectionReferenceAliases aliases,
// CollectionQuerySpace rightHandSide, CollectionQuerySpace rightHandSide,
// String[] aliasedLhsColumnNames, // String[] aliasedLhsColumnNames,
// Join join, Join join,
// JoinFragment joinFragment) { JoinFragment joinFragment) {
// final CollectionPersister persister = rightHandSide.getCollectionPersister(); final CollectionPersister persister = rightHandSide.getCollectionPersister();
// final QueryableCollection queryableCollection = (QueryableCollection) persister; final QueryableCollection queryableCollection = (QueryableCollection) persister;
//
// // for many-to-many we have 3 table aliases. By way of example, consider a normal m-n: User<->Role // for many-to-many we have 3 table aliases. By way of example, consider a normal m-n: User<->Role
// // where User is the FetchOwner and Role (User.roles) is the Fetch. We'd have: // where User is the FetchOwner and Role (User.roles) is the Fetch. We'd have:
// // 1) the owner's table : user - in terms of rendering the joins (not the fetch select fragments), the // 1) the owner's table : user - in terms of rendering the joins (not the fetch select fragments), the
// // lhs table alias is only needed to qualify the lhs join columns, but we already have the qualified // lhs table alias is only needed to qualify the lhs join columns, but we already have the qualified
// // columns here (aliasedLhsColumnNames) // columns here (aliasedLhsColumnNames)
// //final String ownerTableAlias = ...; //final String ownerTableAlias = ...;
// // 2) the m-n table : user_role // 2) the m-n table : user_role
// final String collectionTableAlias = aliases.getCollectionTableAlias(); final String collectionTableAlias = aliases.getCollectionTableAlias();
// // 3) the element table : role // 3) the element table : role
// final String elementTableAlias = aliases.getElementTableAlias(); final String elementTableAlias = aliases.getElementTableAlias();
//
// // somewhere, one of these being empty is causing trouble... // somewhere, one of these being empty is causing trouble...
// if ( StringHelper.isEmpty( collectionTableAlias ) ) { if ( StringHelper.isEmpty( collectionTableAlias ) ) {
// throw new IllegalStateException( "Collection table alias cannot be empty" ); throw new IllegalStateException( "Collection table alias cannot be empty" );
// } }
// if ( StringHelper.isEmpty( elementTableAlias ) ) { if ( StringHelper.isEmpty( elementTableAlias ) ) {
// throw new IllegalStateException( "Collection element (many-to-many) table alias cannot be empty" ); throw new IllegalStateException( "Collection element (many-to-many) table alias cannot be empty" );
// } }
//
// //
// { // {
// // add join fragments from the owner table -> collection table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // add join fragments from the owner table -> collection table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -420,45 +430,45 @@ public class LoadQueryJoinAndFetchProcessor {
// queryableCollection.whereJoinFragment( collectionTableAlias, false, true ) // queryableCollection.whereJoinFragment( collectionTableAlias, false, true )
// ); // );
// } // }
//
// { {
// // add join fragments from the collection table -> element entity table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // add join fragments from the collection table -> element entity table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// final String additionalJoinConditions = resolveAdditionalJoinCondition( final String additionalJoinConditions = resolveAdditionalJoinCondition(
// elementTableAlias, elementTableAlias,
// join.getAnyAdditionalJoinConditions( elementTableAlias ), join.getAnyAdditionalJoinConditions( elementTableAlias ),
// queryableCollection queryableCollection
// ); );
//
// final String manyToManyFilter = persister.getManyToManyFilterFragment( final String manyToManyFilter = persister.getManyToManyFilterFragment(
// collectionTableAlias, collectionTableAlias,
// buildingParameters.getQueryInfluencers().getEnabledFilters() buildingParameters.getQueryInfluencers().getEnabledFilters()
// ); );
//
// final String condition; final String condition;
// if ( StringHelper.isEmpty( manyToManyFilter ) ) { if ( StringHelper.isEmpty( manyToManyFilter ) ) {
// condition = additionalJoinConditions; condition = additionalJoinConditions;
// } }
// else if ( StringHelper.isEmpty( additionalJoinConditions ) ) { else if ( StringHelper.isEmpty( additionalJoinConditions ) ) {
// condition = manyToManyFilter; condition = manyToManyFilter;
// } }
// else { else {
// condition = additionalJoinConditions + " and " + manyToManyFilter; condition = additionalJoinConditions + " and " + manyToManyFilter;
// } }
//
// final OuterJoinLoadable elementPersister = (OuterJoinLoadable) queryableCollection.getElementPersister(); final OuterJoinLoadable elementPersister = (OuterJoinLoadable) queryableCollection.getElementPersister();
//
// addJoins( addJoins(
// joinFragment, joinFragment,
// elementPersister, elementPersister,
// JoinType.LEFT_OUTER_JOIN, JoinType.LEFT_OUTER_JOIN,
// elementTableAlias, elementTableAlias,
// elementPersister.getIdentifierColumnNames(), elementPersister.getIdentifierColumnNames(),
// StringHelper.qualify( collectionTableAlias, queryableCollection.getElementColumnNames() ), StringHelper.qualify( collectionTableAlias, queryableCollection.getElementColumnNames() ),
// condition condition
// ); );
// } }
// } }
//
// private void renderOneToManyJoin( // private void renderOneToManyJoin(
// CollectionReferenceAliases aliases, // CollectionReferenceAliases aliases,
// CollectionQuerySpace rightHandSide, // CollectionQuerySpace rightHandSide,
@ -699,8 +709,9 @@ public class LoadQueryJoinAndFetchProcessor {
selectStatementBuilder.appendSelectClauseFragment( selectStatementBuilder.appendSelectClauseFragment(
joinableCollection.selectFragment( joinableCollection.selectFragment(
(Joinable) queryableCollection.getElementPersister(), (Joinable) queryableCollection.getElementPersister(),
ownerTableAlias, elementTableAlias,
collectionTableAlias, collectionTableAlias,
aliases.getEntityElementColumnAliases().getSuffix(), aliases.getEntityElementColumnAliases().getSuffix(),
aliases.getCollectionColumnAliases().getSuffix(), aliases.getCollectionColumnAliases().getSuffix(),
true true
@ -731,7 +742,7 @@ public class LoadQueryJoinAndFetchProcessor {
final EntityReferenceAliases entityReferenceAliases = new EntityReferenceAliases() { final EntityReferenceAliases entityReferenceAliases = new EntityReferenceAliases() {
@Override @Override
public String getTableAlias() { public String getTableAlias() {
return aliases.getElementTableAlias(); return aliases.getCollectionTableAlias();
} }
@Override @Override

View File

@ -84,8 +84,6 @@ public class ResultSetProcessingContextImpl implements ResultSetProcessingContex
private Map<EntityPersister,Set<EntityKey>> subselectLoadableEntityKeyMap; private Map<EntityPersister,Set<EntityKey>> subselectLoadableEntityKeyMap;
private List<HydratedEntityRegistration> hydratedEntityRegistrationList; private List<HydratedEntityRegistration> hydratedEntityRegistrationList;
private final LockModeResolver lockModeResolverDelegate;
/** /**
* Builds a ResultSetProcessingContextImpl * Builds a ResultSetProcessingContextImpl
* *
@ -132,16 +130,6 @@ public class ResultSetProcessingContextImpl implements ResultSetProcessingContex
} }
} }
} }
this.lockModeResolverDelegate = new LockModeResolver() {
@Override
public LockMode resolveLockMode(EntityReference entityReference) {
if ( queryParameters.getLockOptions() != null && queryParameters.getLockOptions()
.getLockMode() != null ) {
return queryParameters.getLockOptions().getLockMode();
}
return LockMode.READ;
}
};
} }
@Override @Override
@ -175,8 +163,11 @@ public class ResultSetProcessingContextImpl implements ResultSetProcessingContex
@Override @Override
public LockMode resolveLockMode(EntityReference entityReference) { public LockMode resolveLockMode(EntityReference entityReference) {
final LockMode lockMode = lockModeResolverDelegate.resolveLockMode( entityReference ); if ( queryParameters.getLockOptions() != null && queryParameters.getLockOptions()
return LockMode.NONE == lockMode ? LockMode.NONE : lockMode; .getLockMode() != null ) {
return queryParameters.getLockOptions().getLockMode();
}
return LockMode.READ;
} }
private Map<EntityReference,EntityReferenceProcessingState> identifierResolutionContextMap; private Map<EntityReference,EntityReferenceProcessingState> identifierResolutionContextMap;

View File

@ -34,6 +34,7 @@ import org.hibernate.event.spi.EventSource;
import org.hibernate.event.spi.PostLoadEvent; import org.hibernate.event.spi.PostLoadEvent;
import org.hibernate.event.spi.PreLoadEvent; import org.hibernate.event.spi.PreLoadEvent;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.loader.plan2.exec.process.internal.HydratedEntityRegistration; import org.hibernate.loader.plan2.exec.process.internal.HydratedEntityRegistration;
import org.hibernate.loader.plan2.exec.process.internal.ResultSetProcessingContextImpl; import org.hibernate.loader.plan2.exec.process.internal.ResultSetProcessingContextImpl;
import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.loader.spi.AfterLoadAction;
@ -58,7 +59,7 @@ public abstract class AbstractRowReader implements RowReader {
final List<CollectionReferenceInitializer> arrayReferenceInitializers = getArrayReferenceInitializers(); final List<CollectionReferenceInitializer> arrayReferenceInitializers = getArrayReferenceInitializers();
final List<CollectionReferenceInitializer> collectionReferenceInitializers = getCollectionReferenceInitializers(); final List<CollectionReferenceInitializer> collectionReferenceInitializers = getCollectionReferenceInitializers();
final boolean hasEntityReferenceInitializers = entityReferenceInitializers != null && entityReferenceInitializers.size() > 0; final boolean hasEntityReferenceInitializers = CollectionHelper.isNotEmpty( entityReferenceInitializers );
if ( hasEntityReferenceInitializers ) { if ( hasEntityReferenceInitializers ) {
// 1) allow entity references to resolve identifiers (in 2 steps) // 1) allow entity references to resolve identifiers (in 2 steps)