From d43e89cc4a66a1071a715396d43425069a15fe5b Mon Sep 17 00:00:00 2001 From: Gavin Date: Mon, 15 May 2023 15:45:32 +0200 Subject: [PATCH] HHH-16604 partial fix to 'ENUM member of collection' fix for the case of a fully-qualified name, i.e. org.package.Enum.ENUM --- .../sqm/sql/BaseSqmToSqlAstConverter.java | 20 +++++++++++++++-- .../sql/ast/tree/expression/QueryLiteral.java | 22 ++++++++++--------- .../orm/test/query/hql/FunctionTests.java | 9 ++++++++ 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java index 299dd44349..00ffef995b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java @@ -86,6 +86,7 @@ import org.hibernate.metamodel.mapping.SqlExpressible; import org.hibernate.metamodel.mapping.SqlTypedMapping; import org.hibernate.metamodel.mapping.ValueMapping; import org.hibernate.metamodel.mapping.ValuedModelPart; +import org.hibernate.metamodel.mapping.internal.BasicValuedCollectionPart; import org.hibernate.metamodel.mapping.internal.EntityCollectionPart; import org.hibernate.metamodel.mapping.internal.ManyToManyCollectionPart; import org.hibernate.metamodel.mapping.internal.OneToManyCollectionPart; @@ -93,7 +94,6 @@ import org.hibernate.metamodel.mapping.internal.SqlTypedMappingImpl; import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping; import org.hibernate.metamodel.mapping.ordering.OrderByFragment; import org.hibernate.metamodel.model.domain.BasicDomainType; -import org.hibernate.metamodel.model.domain.DiscriminatorSqmPath; import org.hibernate.metamodel.model.domain.EmbeddableDomainType; import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.PersistentAttribute; @@ -6728,7 +6728,23 @@ public abstract class BaseSqmToSqlAstConverter extends Base @Override public Object visitEnumLiteral(SqmEnumLiteral sqmEnumLiteral) { - final BasicValuedMapping inferredType = (BasicValuedMapping) resolveInferredType(); + final MappingModelExpressible inferred = resolveInferredType(); + final SqlExpressible inferredType; + if ( inferred instanceof PluralAttributeMapping ) { + final CollectionPart elementDescriptor = ((PluralAttributeMapping) inferred).getElementDescriptor(); + if ( elementDescriptor instanceof BasicValuedCollectionPart) { + inferredType = (BasicValuedCollectionPart) elementDescriptor; + } + else { + inferredType = null; + } + } + else if ( inferred instanceof BasicValuedMapping ) { + inferredType = (BasicValuedMapping) inferred; + } + else { + inferredType = null; + } if ( inferredType != null ) { return new QueryLiteral<>( inferredType.getJdbcMapping().convertToRelationalValue( sqmEnumLiteral.getEnumValue() ), diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/QueryLiteral.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/QueryLiteral.java index aadefc41f4..a6846dcc53 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/QueryLiteral.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/QueryLiteral.java @@ -11,6 +11,8 @@ import java.sql.SQLException; import org.hibernate.metamodel.mapping.BasicValuedMapping; import org.hibernate.metamodel.mapping.JdbcMapping; +import org.hibernate.metamodel.mapping.JdbcMappingContainer; +import org.hibernate.metamodel.mapping.SqlExpressible; import org.hibernate.query.sqm.sql.internal.DomainResultProducer; import org.hibernate.sql.ast.SqlAstWalker; import org.hibernate.sql.ast.spi.SqlSelection; @@ -29,11 +31,11 @@ import org.hibernate.sql.results.graph.basic.BasicResult; */ public class QueryLiteral implements Literal, DomainResultProducer { private final T value; - private final BasicValuedMapping type; + private final SqlExpressible expressible; - public QueryLiteral(T value, BasicValuedMapping type) { + public QueryLiteral(T value, SqlExpressible expressible) { this.value = value; - this.type = type; + this.expressible = expressible; } @Override @@ -43,7 +45,7 @@ public class QueryLiteral implements Literal, DomainResultProducer { @Override public JdbcMapping getJdbcMapping() { - return type.getJdbcMapping(); + return expressible.getJdbcMapping(); } @Override @@ -52,8 +54,8 @@ public class QueryLiteral implements Literal, DomainResultProducer { } @Override - public BasicValuedMapping getExpressionType() { - return type; + public JdbcMappingContainer getExpressionType() { + return expressible; } @Override @@ -63,7 +65,7 @@ public class QueryLiteral implements Literal, DomainResultProducer { final SqlSelection sqlSelection = creationState.getSqlAstCreationState().getSqlExpressionResolver() .resolveSqlSelection( this, - type.getJdbcMapping().getJdbcJavaType(), + expressible.getJdbcMapping().getJdbcJavaType(), null, creationState.getSqlAstCreationState() .getCreationContext() @@ -74,7 +76,7 @@ public class QueryLiteral implements Literal, DomainResultProducer { return new BasicResult<>( sqlSelection.getValuesArrayPosition(), resultVariable, - type.getJdbcMapping() + expressible.getJdbcMapping() ); } @@ -85,7 +87,7 @@ public class QueryLiteral implements Literal, DomainResultProducer { JdbcParameterBindings jdbcParameterBindings, ExecutionContext executionContext) throws SQLException { //noinspection unchecked - type.getJdbcMapping().getJdbcValueBinder().bind( + expressible.getJdbcMapping().getJdbcValueBinder().bind( statement, getLiteralValue(), startPosition, @@ -97,7 +99,7 @@ public class QueryLiteral implements Literal, DomainResultProducer { public void applySqlSelections(DomainResultCreationState creationState) { creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection( this, - type.getJdbcMapping().getJdbcJavaType(), + expressible.getJdbcMapping().getJdbcJavaType(), null, creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration() ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java index fbbbc43b22..c62a665d12 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java @@ -1911,4 +1911,13 @@ public class FunctionTests { ); } + @Test + public void testMemberOf(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + session.createSelectionQuery("from EntityOfLists where org.hibernate.testing.orm.domain.gambit.EnumValue.THREE member of listOfEnums").getResultList(); + } + ); + } + }