HHH-15073 Test criteria query built from JPA metamodel and involving primitive types

This commit is contained in:
Andrea Boriero 2022-02-08 14:14:22 +01:00 committed by Yoann Rodière
parent c1078b2612
commit 3b6d25425a
2 changed files with 23 additions and 8 deletions

View File

@ -65,6 +65,8 @@ import org.hibernate.sql.exec.internal.CallbackImpl;
import org.hibernate.sql.exec.spi.Callback; import org.hibernate.sql.exec.spi.Callback;
import org.hibernate.sql.results.internal.TupleMetadata; import org.hibernate.sql.results.internal.TupleMetadata;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.PrimitiveJavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.jdbc.JdbcType;
import static org.hibernate.cfg.AvailableSettings.JAKARTA_SHARED_CACHE_RETRIEVE_MODE; import static org.hibernate.cfg.AvailableSettings.JAKARTA_SHARED_CACHE_RETRIEVE_MODE;
@ -279,9 +281,16 @@ public abstract class AbstractSelectionQuery<R>
SqmExpressible<?> sqmExpressible, SqmExpressible<?> sqmExpressible,
SessionFactoryImplementor sessionFactory) { SessionFactoryImplementor sessionFactory) {
assert sqmExpressible != null; assert sqmExpressible != null;
assert sqmExpressible.getExpressibleJavaType() != null; final JavaType<?> expressibleJavaType = sqmExpressible.getExpressibleJavaType();
final Class<?> javaTypeClass = sqmExpressible.getExpressibleJavaType().getJavaTypeClass(); assert expressibleJavaType != null;
final Class<?> javaTypeClass = expressibleJavaType.getJavaTypeClass();
if ( !resultClass.isAssignableFrom( javaTypeClass ) ) { if ( !resultClass.isAssignableFrom( javaTypeClass ) ) {
if ( expressibleJavaType instanceof PrimitiveJavaType ) {
if ( ( (PrimitiveJavaType) expressibleJavaType ).getPrimitiveClass() == resultClass ) {
return;
}
throwQueryTypeMismatchException( resultClass, sqmExpressible );
}
// Special case for date because we always report java.util.Date as expression type // Special case for date because we always report java.util.Date as expression type
// But the expected resultClass could be a subtype of that, so we need to check the JdbcType // But the expected resultClass could be a subtype of that, so we need to check the JdbcType
if ( javaTypeClass == Date.class ) { if ( javaTypeClass == Date.class ) {
@ -315,15 +324,19 @@ public abstract class AbstractSelectionQuery<R>
} }
} }
} }
final String errorMessage = String.format( throwQueryTypeMismatchException( resultClass, sqmExpressible );
"Specified result type [%s] did not match Query selection type [%s] - multiple selections: use Tuple or array",
resultClass.getName(),
sqmExpressible.getExpressibleJavaType().getJavaType().getTypeName()
);
throw new QueryTypeMismatchException( errorMessage );
} }
} }
private static <T> void throwQueryTypeMismatchException(Class<T> resultClass, SqmExpressible<?> sqmExpressible) {
final String errorMessage = String.format(
"Specified result type [%s] did not match Query selection type [%s] - multiple selections: use Tuple or array",
resultClass.getName(),
sqmExpressible.getExpressibleJavaType().getJavaType().getTypeName()
);
throw new QueryTypeMismatchException( errorMessage );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// execution // execution

View File

@ -62,6 +62,8 @@ public class CriteriaPrimitiveIdTest extends BaseCoreFunctionalTestCase {
@Id @Id
private long id; private long id;
private String name;
public MyEntity() { public MyEntity() {
} }