HHH-18610 ColumnReferenceKey for discriminator

This commit is contained in:
Andrea Boriero 2024-11-13 13:10:57 +01:00
parent bfaf3c5931
commit 691604dbfb
3 changed files with 53 additions and 8 deletions

View File

@ -4,6 +4,7 @@
*/
package org.hibernate.query.results.internal;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.SelectableMapping;
@ -19,6 +20,7 @@ import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createDiscriminatorColumnReferenceKey;
/**
* @author Steve Ebersole
@ -65,6 +67,25 @@ public class ResultsHelper {
);
}
public static Expression resolveSqlExpression(
DomainResultCreationStateImpl resolver,
JdbcValuesMetadata jdbcValuesMetadata,
TableReference tableReference,
EntityDiscriminatorMapping discriminatorMapping,
String columnAlias) {
return resolver.resolveSqlExpression(
createDiscriminatorColumnReferenceKey(
tableReference,
discriminatorMapping
),
processingState -> {
final int jdbcPosition = jdbcValuesMetadata.resolveColumnPosition( columnAlias );
final int valuesArrayPosition = jdbcPositionToValuesArrayPosition( jdbcPosition );
return new ResultSetMappingSqlSelection( valuesArrayPosition, discriminatorMapping.getJdbcMapping() );
}
);
}
public static Expression resolveSqlExpression(
DomainResultCreationStateImpl resolver,
TableReference tableReference,

View File

@ -7,6 +7,7 @@ package org.hibernate.query.results.internal.dynamic;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
@ -259,7 +260,7 @@ public class DynamicResultBuilderEntityStandard
}
if ( discriminatorColumnName != null ) {
resolveSqlSelection(
resolveDiscriminatorSqlSelection(
discriminatorColumnName,
tableReference,
entityMapping.getDiscriminatorMapping(),
@ -284,6 +285,25 @@ public class DynamicResultBuilderEntityStandard
}
}
private static void resolveDiscriminatorSqlSelection(String columnAlias, TableReference tableReference, EntityDiscriminatorMapping discriminatorMapping, JdbcValuesMetadata jdbcResultsMetadata, DomainResultCreationState domainResultCreationState) {
final DomainResultCreationStateImpl creationStateImpl = impl( domainResultCreationState );
creationStateImpl.resolveSqlSelection(
ResultsHelper.resolveSqlExpression(
creationStateImpl,
jdbcResultsMetadata,
tableReference,
discriminatorMapping,
columnAlias
),
discriminatorMapping.getJdbcMapping().getJdbcJavaType(),
null,
domainResultCreationState.getSqlAstCreationState()
.getCreationContext()
.getSessionFactory()
.getTypeConfiguration()
);
}
private FetchBuilder findIdFetchBuilder() {
return findFetchBuilder( entityMapping.getIdentifierMapping() );
}

View File

@ -6,10 +6,10 @@ package org.hibernate.sql.ast.spi;
import java.util.function.Function;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.mapping.SelectablePath;
import org.hibernate.metamodel.mapping.internal.DiscriminatorTypeImpl;
import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.NestedColumnReference;
@ -91,6 +91,15 @@ public interface SqlExpressionResolver {
return createColumnReferenceKey( tableReference, selectable.getSelectablePath(), selectable.getJdbcMapping() );
}
/**
* Convenience form for creating a key from TableReference and EntityDiscriminatorMapping
*/
static ColumnReferenceKey createDiscriminatorColumnReferenceKey(TableReference tableReference, EntityDiscriminatorMapping discriminatorMapping) {
assert tableReference.containsAffectedTableName( discriminatorMapping.getContainingTableExpression() )
: String.format( ROOT, "Expecting tables to match between TableReference (%s) and SelectableMapping (%s)", tableReference.getTableId(), discriminatorMapping.getContainingTableExpression() );
return createColumnReferenceKey( tableReference, discriminatorMapping.getSelectablePath(), discriminatorMapping.getUnderlyingJdbcMapping() );
}
default Expression resolveSqlExpression(TableReference tableReference, SelectableMapping selectableMapping) {
return resolveSqlExpression(
createColumnReferenceKey( tableReference, selectableMapping ),
@ -127,13 +136,8 @@ public interface SqlExpressionResolver {
public ColumnReferenceKey(String tableQualifier, SelectablePath selectablePath, JdbcMapping jdbcMapping) {
this.tableQualifier = tableQualifier;
this.selectablePath = selectablePath;
if ( jdbcMapping instanceof DiscriminatorTypeImpl discriminatorType ) {
this.jdbcMapping = discriminatorType.getUnderlyingJdbcMapping();
}
else {
this.jdbcMapping = jdbcMapping;
}
}
@Override
public boolean equals(Object o) {