HHH-8276 - Integrate LoadPlans into UniqueEntityLoader (PoC)
This commit is contained in:
parent
c5f3ddeccb
commit
aaadcd74ee
|
@ -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(
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class AliasResolutionContextImpl implements AliasResolutionContext {
|
||||||
|
|
||||||
private Map<String,EntityReferenceAliases> entityReferenceAliasesMap;
|
private Map<String,EntityReferenceAliases> entityReferenceAliasesMap;
|
||||||
private Map<String,CollectionReferenceAliases> collectionReferenceAliasesMap;
|
private Map<String,CollectionReferenceAliases> collectionReferenceAliasesMap;
|
||||||
private Map<String, String> querySpaceUidToSqlTableAliasMap;
|
private Map<String,String> querySpaceUidToSqlTableAliasMap;
|
||||||
|
|
||||||
private Map<String,String> compositeQuerySpaceUidToSqlTableAliasMap;
|
private Map<String,String> compositeQuerySpaceUidToSqlTableAliasMap;
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue