HHH-17406 Remove instanceof / cast usages of `BasicValuedModelPart`

This should help with type pollution, though it's not strictly needed for the scope of the generated values change.
This commit is contained in:
Marco Belladelli 2023-12-21 15:27:21 +01:00 committed by Christian Beikov
parent 599be89308
commit 3ac0b8cb5e
17 changed files with 113 additions and 104 deletions

View File

@ -674,10 +674,11 @@ public class HbmResultSetMappingDescriptor implements NamedResultSetMappingDescr
navigablePath = navigablePath.append( fetchable.getFetchableName() );
}
if ( fetchable instanceof BasicValuedModelPart ) {
final BasicValuedModelPart basicPart = fetchable.asBasicValuedModelPart();
if ( basicPart != null ) {
return new FetchMementoBasicStandard(
navigablePath,
(BasicValuedModelPart) fetchable,
basicPart,
columnAliases.get( 0 )
);
}

View File

@ -347,14 +347,9 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
final ModelPart subPart = entityMapping.findSubPart( propertyPath, null );
//noinspection StatementWithEmptyBody
if ( subPart == null ) {
// throw an exception
}
if ( subPart instanceof BasicValuedModelPart ) {
final BasicValuedModelPart basicPart = subPart != null ? subPart.asBasicValuedModelPart() : null;
if ( basicPart != null ) {
assert columnNames.size() == 1;
final BasicValuedModelPart basicPart = (BasicValuedModelPart) subPart;
return new ModelPartResultMementoBasicImpl( path, basicPart, columnNames.get( 0 ) );
}
@ -405,10 +400,9 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
}
private FetchMemento getFetchMemento(NavigablePath navigablePath, ModelPart subPart) {
if ( subPart instanceof BasicValuedModelPart ) {
final BasicValuedModelPart basicPart = subPart.asBasicValuedModelPart();
if ( basicPart != null ) {
assert columnNames.size() == 1;
final BasicValuedModelPart basicPart = (BasicValuedModelPart) subPart;
return new FetchMementoBasicStandard( navigablePath, basicPart, columnNames.get( 0 ) );
}
else if ( subPart instanceof EntityValuedFetchable ) {

View File

@ -974,7 +974,7 @@ public class LoaderSelectBuilder {
}
else if ( fetchDepth > maximumFetchDepth + 1 ) {
// We can preserve the existing value of joined for basic and embedded values
if ( !( fetchable instanceof BasicValuedModelPart ) && !( fetchable instanceof EmbeddedAttributeMapping ) ) {
if ( fetchable.asBasicValuedModelPart() == null && !( fetchable instanceof EmbeddedAttributeMapping ) ) {
joined = false;
}
}

View File

@ -8,6 +8,8 @@ package org.hibernate.metamodel.mapping;
import org.hibernate.persister.entity.UnionSubclassEntityPersister;
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
/**
* @author Steve Ebersole
*/
@ -134,18 +136,21 @@ public class MappingModelHelper {
}
return true;
}
else if ( attribute1 instanceof BasicValuedModelPart ) {
final BasicValuedModelPart basic1 = (BasicValuedModelPart) attribute1;
final BasicValuedModelPart basic2 = (BasicValuedModelPart) attribute2;
if ( !basic1.getSelectionExpression().equals( basic2.getSelectionExpression() ) ) {
return false;
else {
final BasicValuedModelPart basic1 = attribute1.asBasicValuedModelPart();
if ( basic1 != null ) {
final BasicValuedModelPart basic2 = castNonNull( attribute2.asBasicValuedModelPart() );
if ( !basic1.getSelectionExpression().equals( basic2.getSelectionExpression() ) ) {
return false;
}
if ( basic1.getContainingTableExpression().equals( basic2.getContainingTableExpression() ) ) {
return true;
}
// For union subclass mappings we also consider mappings compatible that just match the selection expression,
// because we match up columns of disjoint union subclass types by column name
return attribute1.findContainingEntityMapping()
.getEntityPersister() instanceof UnionSubclassEntityPersister;
}
if ( basic1.getContainingTableExpression().equals( basic2.getContainingTableExpression() ) ) {
return true;
}
// For union subclass mappings we also consider mappings compatible that just match the selection expression,
// because we match up columns of disjoint union subclass types by column name
return attribute1.findContainingEntityMapping().getEntityPersister() instanceof UnionSubclassEntityPersister;
}
return false;
}

View File

@ -32,6 +32,7 @@ import org.hibernate.sql.ast.tree.select.SortSpecification;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.internal.SqlSelectionImpl;
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
/**
@ -61,8 +62,8 @@ public abstract class AbstractDomainPath implements DomainPath {
TableGroup tableGroup,
String modelPartName,
SqlAstCreationState creationState) {
if ( referenceModelPart instanceof BasicValuedModelPart ) {
final BasicValuedModelPart selection = (BasicValuedModelPart) referenceModelPart;
final BasicValuedModelPart selection = referenceModelPart.asBasicValuedModelPart();
if ( selection != null ) {
final TableReference tableReference = tableGroup.resolveTableReference(
null,
selection,
@ -104,7 +105,7 @@ public abstract class AbstractDomainPath implements DomainPath {
}
else {
ModelPart subPart = embeddableValuedModelPart.findSubPart( modelPartName, null );
assert subPart instanceof BasicValuedModelPart;
assert subPart.asBasicValuedModelPart() != null;
return resolve( subPart, ast, tableGroup, modelPartName, creationState );
}
}
@ -144,9 +145,10 @@ public abstract class AbstractDomainPath implements DomainPath {
SortDirection sortOrder,
NullPrecedence nullPrecedence,
SqlAstCreationState creationState) {
if ( referenceModelPart instanceof BasicValuedModelPart ) {
final BasicValuedModelPart basicPart = referenceModelPart.asBasicValuedModelPart();
if ( basicPart != null ) {
addSortSpecification(
(BasicValuedModelPart) referenceModelPart,
basicPart,
ast,
tableGroup,
collation,
@ -231,9 +233,8 @@ public abstract class AbstractDomainPath implements DomainPath {
}
else {
ModelPart subPart = embeddableValuedModelPart.findSubPart( modelPartName, null );
assert subPart instanceof BasicValuedModelPart;
addSortSpecification(
(BasicValuedModelPart) subPart,
castNonNull( subPart.asBasicValuedModelPart() ),
ast,
tableGroup,
collation,

View File

@ -620,14 +620,15 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple
final String collectionTableName = ( (CollectionMutationTarget) getCollectionDescriptor() ).getCollectionTableMapping().getTableName();
if ( fkTargetModelPart instanceof BasicValuedModelPart ) {
final BasicValuedModelPart basicFkTarget = fkTargetModelPart.asBasicValuedModelPart();
if ( basicFkTarget != null ) {
return createSimpleForeignKeyDescriptor(
fkBootDescriptorSource,
entityType,
creationProcess,
dialect,
collectionTableName,
(BasicValuedModelPart) fkTargetModelPart
basicFkTarget
);
}

View File

@ -101,6 +101,7 @@ import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
import static org.hibernate.metamodel.mapping.MappingModelCreationLogging.MAPPING_MODEL_CREATION_MESSAGE_LOGGER;
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
@ -769,9 +770,8 @@ public class MappingModelCreationHelper {
if ( keyType instanceof BasicType ) {
assert bootValueMappingKey.getColumnSpan() == 1;
assert fkTargetPart instanceof BasicValuedModelPart;
final BasicValuedModelPart simpleFkTargetPart = (BasicValuedModelPart) fkTargetPart;
final BasicValuedModelPart simpleFkTargetPart = castNonNull( fkTargetPart.asBasicValuedModelPart() );
final String keyTableExpression = collectionTableName;//getTableIdentifierExpression( bootValueMappingKey.getTable(), creationProcess );
final SelectableMapping keySelectableMapping = SelectableMappingImpl.from(
@ -921,8 +921,8 @@ public class MappingModelCreationHelper {
fkTarget = referencedEntityDescriptor.findByPath( bootValueMapping.getReferencedPropertyName() );
}
if ( fkTarget instanceof BasicValuedModelPart ) {
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
final BasicValuedModelPart simpleFkTarget = fkTarget.asBasicValuedModelPart();
if ( simpleFkTarget != null ) {
final Iterator<Selectable> columnIterator = bootValueMapping.getSelectables().iterator();
final Table table = bootValueMapping.getTable();
final String tableExpression = getTableIdentifierExpression( table, creationProcess );
@ -1597,8 +1597,7 @@ public class MappingModelCreationHelper {
return new SqlTuple( columnReferences, modelPart );
}
else {
assert modelPart instanceof BasicValuedModelPart;
final BasicValuedModelPart basicPart = (BasicValuedModelPart) modelPart;
final BasicValuedModelPart basicPart = castNonNull( modelPart.asBasicValuedModelPart() );
final String qualifier;
if ( tableGroup == null ) {
qualifier = basicPart.getContainingTableExpression();

View File

@ -227,7 +227,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
public ForeignKeyDescriptor withTargetPart(ValuedModelPart targetPart) {
return new SimpleForeignKeyDescriptor(
keySide.getModelPart(),
(BasicValuedModelPart) targetPart,
targetPart.asBasicValuedModelPart(),
refersToPrimaryKey,
hasConstraint,
false

View File

@ -1907,7 +1907,7 @@ public abstract class AbstractEntityPersister
// Ignore plural attributes
if ( !( fetchable instanceof PluralAttributeMapping ) ) {
final FetchTiming fetchTiming = fetchable.getMappedFetchOptions().getTiming();
if ( fetchable instanceof BasicValuedModelPart ) {
if ( fetchable.asBasicValuedModelPart() != null ) {
// Ignore lazy basic columns
if ( fetchTiming == FetchTiming.DELAYED ) {
continue;
@ -4662,7 +4662,7 @@ public abstract class AbstractEntityPersister
final List<ModelPart> generatedBasicAttributes = new ArrayList<>( originalSize );
for ( AttributeMapping generatedAttribute : generatedAttributes ) {
// todo (7.0) : support non selectable mappings? Component, ToOneAttributeMapping, ...
if ( generatedAttribute instanceof BasicValuedModelPart
if ( generatedAttribute.asBasicValuedModelPart() != null
&& generatedAttribute.getContainingTableExpression().equals( getSubclassTableName( 0 ) ) ) {
generatedBasicAttributes.add( generatedAttribute );
}

View File

@ -40,8 +40,9 @@ public class ImplicitModelPartResultMemento implements ModelPartResultMemento {
public ResultBuilder resolve(
Consumer<String> querySpaceConsumer,
ResultSetMappingResolutionContext context) {
if ( referencedModelPart instanceof BasicValuedModelPart ) {
return new ImplicitModelPartResultBuilderBasic( navigablePath, (BasicValuedModelPart) referencedModelPart );
final BasicValuedModelPart basicPart = referencedModelPart.asBasicValuedModelPart();
if ( basicPart != null ) {
return new ImplicitModelPartResultBuilderBasic( navigablePath, basicPart );
}
if ( referencedModelPart instanceof EmbeddableValuedModelPart ) {

View File

@ -87,11 +87,11 @@ public class ResultMementoEntityJpa implements ResultMementoEntity, FetchMemento
// Implicit basic fetches are DELAYED by default, so register fetch builders for the remaining basic fetchables
entityDescriptor.forEachAttributeMapping(
attributeMapping -> {
final Function<String, FetchBuilder> fetchBuilderCreator;
if ( attributeMapping instanceof BasicValuedModelPart ) {
fetchBuilderCreator = k -> new DelayedFetchBuilderBasicPart(
final BasicValuedModelPart basicPart = attributeMapping.asBasicValuedModelPart();
if ( basicPart != null ) {
final Function<String, FetchBuilder> fetchBuilderCreator = k -> new DelayedFetchBuilderBasicPart(
navigablePath.append( k ),
(BasicValuedModelPart) attributeMapping,
basicPart,
isEnhancedForLazyLoading
);
explicitFetchBuilderMap.computeIfAbsent(

View File

@ -269,8 +269,8 @@ public class Builders {
NavigablePath fetchPath,
Fetchable fetchable,
DomainResultCreationState creationState) {
if ( fetchable instanceof BasicValuedModelPart ) {
final BasicValuedModelPart basicValuedFetchable = (BasicValuedModelPart) fetchable;
final BasicValuedModelPart basicValuedFetchable = fetchable.asBasicValuedModelPart();
if ( basicValuedFetchable != null ) {
return new ImplicitFetchBuilderBasic( fetchPath, basicValuedFetchable, creationState );
}

View File

@ -83,7 +83,8 @@ public class DynamicFetchBuilderStandard
final Fetchable attributeMapping = (Fetchable) parent.getReferencedMappingContainer().findSubPart( fetchableName, null );
final SqlExpressionResolver sqlExpressionResolver = domainResultCreationState.getSqlAstCreationState().getSqlExpressionResolver();
if ( attributeMapping instanceof BasicValuedModelPart ) {
final BasicValuedModelPart basicPart = attributeMapping.asBasicValuedModelPart();
if ( basicPart != null ) {
attributeMapping.forEachSelectable(
getSelectableConsumer(
fetchPath,
@ -92,7 +93,7 @@ public class DynamicFetchBuilderStandard
creationStateImpl,
ownerTableGroup,
sqlExpressionResolver,
(BasicValuedModelPart) attributeMapping
basicPart
)
);
return parent.generateFetchableFetch(

View File

@ -25,6 +25,8 @@ import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.predicate.InListPredicate;
import org.hibernate.sql.exec.spi.ExecutionContext;
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
/**
* MatchingIdRestrictionProducer producing a restriction based on an in-values-list predicate. E.g.:
*
@ -88,7 +90,7 @@ public class InPredicateRestrictionProducer implements MatchingIdRestrictionProd
final InListPredicate predicate;
if ( idColumnCount == 1 ) {
final BasicValuedModelPart basicIdMapping = (BasicValuedModelPart) identifierMapping;
final BasicValuedModelPart basicIdMapping = castNonNull( identifierMapping.asBasicValuedModelPart() );
final String idColumn = basicIdMapping.getSelectionExpression();
final Expression inFixture = new ColumnReference(
mutatingTableReference,

View File

@ -2991,7 +2991,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
final ModelPart subPart = parentType.findSubPart( attributeName );
final EntityNameUse entityNameUse;
// We only apply this optimization for basic valued model parts for now
if ( subPart instanceof BasicValuedModelPart ) {
if ( subPart.asBasicValuedModelPart() != null ) {
entityNameUse = EntityNameUse.OPTIONAL_TREAT;
}
else {
@ -4206,50 +4206,52 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
tableGroup
);
}
else if ( actualModelPart instanceof BasicValuedModelPart ) {
final BasicValuedModelPart mapping = (BasicValuedModelPart) actualModelPart;
final TableReference tableReference = tableGroup.resolveTableReference(
navigablePath.append( actualModelPart.getPartName() ),
mapping,
mapping.getContainingTableExpression()
);
else {
final BasicValuedModelPart mapping = actualModelPart.asBasicValuedModelPart();
if ( mapping != null ) {
final TableReference tableReference = tableGroup.resolveTableReference(
navigablePath.append( actualModelPart.getPartName() ),
mapping,
mapping.getContainingTableExpression()
);
final Expression expression = getSqlExpressionResolver().resolveSqlExpression(
tableReference,
mapping
);
final ColumnReference columnReference;
if ( expression instanceof ColumnReference ) {
columnReference = (ColumnReference) expression;
final Expression expression = getSqlExpressionResolver().resolveSqlExpression(
tableReference,
mapping
);
final ColumnReference columnReference;
if ( expression instanceof ColumnReference ) {
columnReference = (ColumnReference) expression;
}
else if ( expression instanceof SqlSelectionExpression ) {
final Expression selectedExpression = ( (SqlSelectionExpression) expression ).getSelection().getExpression();
assert selectedExpression instanceof ColumnReference;
columnReference = (ColumnReference) selectedExpression;
}
else {
throw new UnsupportedOperationException( "Unsupported basic-valued path expression : " + expression );
}
result = new BasicValuedPathInterpretation<>(
columnReference,
navigablePath,
mapping,
tableGroup
);
}
else if ( expression instanceof SqlSelectionExpression ) {
final Expression selectedExpression = ( (SqlSelectionExpression) expression ).getSelection().getExpression();
assert selectedExpression instanceof ColumnReference;
columnReference = (ColumnReference) selectedExpression;
else if ( actualModelPart instanceof AnonymousTupleTableGroupProducer ) {
throw new SemanticException(
"The derived SqmFrom" + ( (AnonymousTupleType<?>) path.getReferencedPathSource() ).getComponentNames() + " can not be used in a context where the expression needs to " +
"be expanded to identifying parts, because a derived model part does not have identifying parts. " +
"Replace uses of the root with paths instead e.g. `derivedRoot.get(\"alias1\")` or `derivedRoot.alias1`"
);
}
else {
throw new UnsupportedOperationException( "Unsupported basic-valued path expression : " + expression );
throw new SemanticException(
"The SqmFrom node [" + path + "] can not be used in a context where the expression needs to " +
"be expanded to identifying parts, because the model part [" + actualModelPart +
"] does not have identifying parts."
);
}
result = new BasicValuedPathInterpretation<>(
columnReference,
navigablePath,
mapping,
tableGroup
);
}
else if ( actualModelPart instanceof AnonymousTupleTableGroupProducer ) {
throw new SemanticException(
"The derived SqmFrom" + ( (AnonymousTupleType<?>) path.getReferencedPathSource() ).getComponentNames() + " can not be used in a context where the expression needs to " +
"be expanded to identifying parts, because a derived model part does not have identifying parts. " +
"Replace uses of the root with paths instead e.g. `derivedRoot.get(\"alias1\")` or `derivedRoot.alias1`"
);
}
else {
throw new SemanticException(
"The SqmFrom node [" + path + "] can not be used in a context where the expression needs to " +
"be expanded to identifying parts, because the model part [" + actualModelPart +
"] does not have identifying parts."
);
}
return withTreatRestriction( result, path );
@ -4434,9 +4436,8 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
final TableReference tableReference = tableGroup.resolveTableReference( toOneMapping.getContainingTableExpression() );
final ModelPart fkKeyPart = fkDescriptor.getPart( toOneMapping.getSideNature() );
if ( fkKeyPart instanceof BasicValuedModelPart ) {
final BasicValuedModelPart basicFkPart = (BasicValuedModelPart) fkKeyPart;
final BasicValuedModelPart basicFkPart = fkKeyPart.asBasicValuedModelPart();
if ( basicFkPart != null ) {
return getSqlExpressionResolver().resolveSqlExpression(
tableReference,
basicFkPart
@ -4965,8 +4966,9 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
)
);
final Set<String> compatibleTableExpressions;
if ( modelPart instanceof BasicValuedModelPart ) {
compatibleTableExpressions = Collections.singleton( ( (BasicValuedModelPart) modelPart ).getContainingTableExpression() );
final BasicValuedModelPart basicPart = modelPart.asBasicValuedModelPart();
if ( basicPart != null ) {
compatibleTableExpressions = Collections.singleton( basicPart.getContainingTableExpression() );
}
else if ( modelPart instanceof EmbeddableValuedModelPart ) {
compatibleTableExpressions = Collections.singleton( ( (EmbeddableValuedModelPart) modelPart ).getContainingTableExpression() );

View File

@ -34,6 +34,7 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.update.Assignable;
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
import static org.hibernate.query.sqm.internal.SqmUtil.needsTargetTableMapping;
/**
@ -81,22 +82,22 @@ public class BasicValuedPathInterpretation<T> extends AbstractSqmPathInterpretat
}
}
final BasicValuedModelPart mapping;
final ModelPart modelPart;
if ( needsTargetTableMapping( sqmPath, modelPartContainer ) ) {
// We have to make sure we render the column of the target table
mapping = (BasicValuedModelPart) ( (ManagedMappingType) modelPartContainer.getPartMappingType() ).findSubPart(
modelPart = ( (ManagedMappingType) modelPartContainer.getPartMappingType() ).findSubPart(
sqmPath.getReferencedPathSource().getPathName(),
treatTarget
);
}
else {
mapping = (BasicValuedModelPart) modelPartContainer.findSubPart(
modelPart = modelPartContainer.findSubPart(
sqmPath.getReferencedPathSource().getPathName(),
treatTarget
);
}
if ( mapping == null ) {
if ( modelPart == null ) {
if ( jpaQueryComplianceEnabled ) {
// to get the better error, see if we got nothing because of treat handling
final ModelPart subPart = tableGroup.getModelPart().findSubPart(
@ -111,6 +112,7 @@ public class BasicValuedPathInterpretation<T> extends AbstractSqmPathInterpretat
throw new UnknownPathException( "Path '" + sqmPath.getNavigablePath() + "' did not reference a known model part" );
}
final BasicValuedModelPart mapping = castNonNull( modelPart.asBasicValuedModelPart() );
final TableReference tableReference = tableGroup.resolveTableReference(
sqmPath.getNavigablePath(),
mapping,

View File

@ -325,8 +325,8 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
sqlExpression = new SqlTuple( expressions, entityMappingType );
}
else {
if ( resultModelPart instanceof BasicValuedModelPart ) {
final BasicValuedModelPart basicValuedModelPart = (BasicValuedModelPart) resultModelPart;
final BasicValuedModelPart basicValuedModelPart = resultModelPart.asBasicValuedModelPart();
if ( basicValuedModelPart != null ) {
final TableReference tableReference = tableGroup.resolveTableReference(
navigablePath,
basicValuedModelPart,