HHH-16604 partial fix to 'ENUM member of collection'

fix for the case of a fully-qualified name, i.e. org.package.Enum.ENUM
This commit is contained in:
Gavin 2023-05-15 15:45:32 +02:00 committed by Gavin King
parent 47915cfe5f
commit d43e89cc4a
3 changed files with 39 additions and 12 deletions

View File

@ -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<T extends Statement> 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() ),

View File

@ -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<T> implements Literal, DomainResultProducer<T> {
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<T> implements Literal, DomainResultProducer<T> {
@Override
public JdbcMapping getJdbcMapping() {
return type.getJdbcMapping();
return expressible.getJdbcMapping();
}
@Override
@ -52,8 +54,8 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
}
@Override
public BasicValuedMapping getExpressionType() {
return type;
public JdbcMappingContainer getExpressionType() {
return expressible;
}
@Override
@ -63,7 +65,7 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
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<T> implements Literal, DomainResultProducer<T> {
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
resultVariable,
type.getJdbcMapping()
expressible.getJdbcMapping()
);
}
@ -85,7 +87,7 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
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<T> implements Literal, DomainResultProducer<T> {
public void applySqlSelections(DomainResultCreationState creationState) {
creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
this,
type.getJdbcMapping().getJdbcJavaType(),
expressible.getJdbcMapping().getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

View File

@ -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();
}
);
}
}