HHH-16494 Treat entity and attribute joins for inheritance subtypes

This commit is contained in:
Marco Belladelli 2023-05-08 11:11:38 +02:00
parent 3e3fd6f0be
commit fed020e110
1 changed files with 36 additions and 4 deletions

View File

@ -50,7 +50,7 @@ import org.hibernate.id.CompositeNestedGeneratedValueGenerator;
import org.hibernate.id.OptimizableGenerator;
import org.hibernate.id.enhanced.Optimizer;
import org.hibernate.internal.FilterHelper;
import org.hibernate.internal.util.MutableObject;
import org.hibernate.internal.util.MutableBoolean;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.internal.util.collections.Stack;
import org.hibernate.internal.util.collections.StandardStack;
@ -3333,6 +3333,23 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
registerEntityNameProjectionUsage( sqmJoin, getActualTableGroup( joinedTableGroup, sqmJoin ) );
}
registerPathAttributeEntityNameUsage( sqmJoin, ownerTableGroup );
if ( !sqmJoin.hasTreats() && sqmJoin.getNodeType().getSqmPathType() instanceof EntityDomainType ) {
final EntityDomainType<?> entityDomainType = (EntityDomainType<?>) sqmJoin.getNodeType().getSqmPathType();
final TableGroup elementTableGroup = joinedTableGroup instanceof PluralTableGroup ?
( (PluralTableGroup) joinedTableGroup ).getElementTableGroup() :
joinedTableGroup;
final EntityValuedModelPart entityModelPart = (EntityValuedModelPart) elementTableGroup.getModelPart();
final EntityPersister entityDescriptor = entityModelPart.getEntityMappingType().getEntityPersister();
if ( entityDescriptor.getSuperMappingType() != null ) {
// This is a non-treated join with an entity which is an inheritance subtype,
// register a TREAT entity name use to filter only the entities of the correct type.
registerEntityNameUsage(
getActualTableGroup( joinedTableGroup, sqmJoin ),
EntityNameUse.TREAT,
entityDomainType.getHibernateEntityName()
);
}
}
// add any additional join restrictions
if ( sqmJoin.getJoinPredicate() != null ) {
@ -3391,7 +3408,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
}
private TableGroup consumeEntityJoin(SqmEntityJoin<?> sqmJoin, TableGroup lhsTableGroup, boolean transitive) {
final MutableObject<Predicate> predicate = new MutableObject<>();
final MutableBoolean needsTreat = new MutableBoolean( false );
final EntityPersister entityDescriptor = resolveEntityPersister( sqmJoin.getReferencedPathSource() );
final SqlAstJoinType correspondingSqlJoinType = sqmJoin.getSqmJoinType().getCorrespondingSqlJoinType();
@ -3400,16 +3417,21 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
sqmJoin.getNavigablePath(),
sqmJoin.getExplicitAlias(),
null,
() -> p -> predicate.set( combinePredicates( predicate.get(), p ) ),
() -> p -> needsTreat.setValue( true ),
this
);
registerSqmFromTableGroup( sqmJoin, tableGroup );
if ( needsTreat.getValue() ) {
// Register new treat to apply the discriminator condition to the table reference itself, see #pruneTableGroupJoins
registerEntityNameUsage( tableGroup, EntityNameUse.TREAT, entityDescriptor.getEntityName() );
}
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
sqmJoin.getNavigablePath(),
correspondingSqlJoinType,
tableGroup,
predicate.get()
null
);
if ( sqmJoin.getJoinPredicate() != null ) {
@ -4549,6 +4571,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
null,
this
);
registerProjectionUsageFromDescriptor( tableGroup, indexDescriptor );
final CollectionPart valueDescriptor = mapDescriptor.getElementDescriptor();
final NavigablePath valueNavigablePath = mapNavigablePath.append( valueDescriptor.getPartName() );
@ -4558,6 +4581,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
null,
this
);
registerProjectionUsageFromDescriptor( tableGroup, valueDescriptor );
return new DomainResultProducer<Map.Entry<Object, Object>>() {
@Override
@ -4577,6 +4601,14 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
};
}
private void registerProjectionUsageFromDescriptor(TableGroup tableGroup, CollectionPart descriptor) {
if ( descriptor instanceof EntityCollectionPart ) {
final EntityCollectionPart entityCollectionPart = (EntityCollectionPart) descriptor;
final EntityMappingType entityMappingType = entityCollectionPart.getEntityMappingType();
registerEntityNameUsage( tableGroup, EntityNameUse.PROJECTION, entityMappingType.getEntityName(), true );
}
}
protected Expression createCorrelatedAggregateSubQuery(
AbstractSqmSpecificPluralPartPath<?> pluralPartPath,
boolean index,