From c6bc135b2df7d8a02ea8e7f0105ee4fb7cd17462 Mon Sep 17 00:00:00 2001 From: Marco Belladelli Date: Tue, 21 Nov 2023 14:24:45 +0100 Subject: [PATCH] HHH-17454 Correct type checking with concrete generic types --- .../query/sqm/internal/TypecheckUtil.java | 30 +++++++++++-------- .../tree/domain/SqmBasicValuedSimplePath.java | 3 +- .../domain/SqmEmbeddedValuedSimplePath.java | 3 +- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/TypecheckUtil.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/TypecheckUtil.java index 57a8699054..e4384b7e15 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/TypecheckUtil.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/TypecheckUtil.java @@ -7,13 +7,13 @@ package org.hibernate.query.sqm.internal; import jakarta.persistence.criteria.Expression; +import jakarta.persistence.metamodel.EmbeddableType; import jakarta.persistence.metamodel.EntityType; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.model.domain.DomainType; import org.hibernate.metamodel.model.domain.TupleType; import org.hibernate.metamodel.model.domain.internal.DiscriminatorSqmPathSource; -import org.hibernate.metamodel.model.domain.internal.EmbeddedSqmPathSource; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.query.SemanticException; import org.hibernate.query.sqm.BinaryArithmeticOperator; @@ -119,10 +119,10 @@ public class TypecheckUtil { // for embeddables, the embeddable class must match exactly - if ( lhsType instanceof EmbeddedSqmPathSource && rhsType instanceof EmbeddedSqmPathSource ) { + if ( lhsType instanceof EmbeddableType && rhsType instanceof EmbeddableType ) { return areEmbeddableTypesComparable( - (EmbeddedSqmPathSource) lhsType, - (EmbeddedSqmPathSource) rhsType + (EmbeddableType) lhsType, + (EmbeddableType) rhsType ); } @@ -134,8 +134,8 @@ public class TypecheckUtil { // allow comparing an embeddable against a tuple literal - if ( lhsType instanceof EmbeddedSqmPathSource && rhsType instanceof TupleType - || rhsType instanceof EmbeddedSqmPathSource && lhsType instanceof TupleType ) { + if ( lhsType instanceof EmbeddableType && rhsType instanceof TupleType + || rhsType instanceof EmbeddableType && lhsType instanceof TupleType ) { // TODO: do something meaningful here return true; } @@ -192,10 +192,10 @@ public class TypecheckUtil { } private static boolean areEmbeddableTypesComparable( - EmbeddedSqmPathSource lhsType, - EmbeddedSqmPathSource rhsType) { + EmbeddableType lhsType, + EmbeddableType rhsType) { // no polymorphism for embeddable types - return rhsType.getNodeJavaType() == lhsType.getNodeJavaType(); + return rhsType.getJavaType() == lhsType.getJavaType(); } private static boolean areTupleTypesComparable( @@ -340,9 +340,9 @@ public class TypecheckUtil { } // allow comparing literal null to things - if ( !(left instanceof SqmLiteralNull) && !(right instanceof SqmLiteralNull) ) { - final SqmExpressible leftType = left.getNodeType(); - final SqmExpressible rightType = right.getNodeType(); + if ( !( left instanceof SqmLiteralNull ) && !( right instanceof SqmLiteralNull ) ) { + final SqmExpressible leftType = getNodeType( left ); + final SqmExpressible rightType = getNodeType( right ); if ( !areTypesComparable( leftType, rightType, factory ) ) { throw new SemanticException( String.format( @@ -355,6 +355,12 @@ public class TypecheckUtil { } } + private static SqmExpressible getNodeType(SqmExpression expression) { + return expression instanceof SqmPath ? + ( (SqmPath) expression ).getResolvedModel().getSqmType() : + expression.getNodeType(); + } + /** * @see TypecheckUtil#assertComparable(Expression, Expression, SessionFactoryImplementor) */ diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmBasicValuedSimplePath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmBasicValuedSimplePath.java index bb7e62bf81..5e07bb77fd 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmBasicValuedSimplePath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmBasicValuedSimplePath.java @@ -132,7 +132,8 @@ public class SqmBasicValuedSimplePath @Override public DomainType getSqmType() { - return getNodeType().getSqmType(); + //noinspection unchecked + return (DomainType) getResolvedModel().getSqmType(); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmEmbeddedValuedSimplePath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmEmbeddedValuedSimplePath.java index 8b2822d93b..cce753c1ce 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmEmbeddedValuedSimplePath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmEmbeddedValuedSimplePath.java @@ -77,7 +77,8 @@ public class SqmEmbeddedValuedSimplePath @Override public DomainType getSqmType() { - return getReferencedPathSource().getSqmType(); + //noinspection unchecked + return (DomainType) getResolvedModel().getSqmType(); } @Override