HHH-18450 Handle array result types for multi-valued parameters

Also fix an NPE in SqmSelectionQueryImpl#determineResultType
This commit is contained in:
Marco Belladelli 2024-08-12 10:16:59 +02:00
parent 7893d1066f
commit 3521857ef2
2 changed files with 16 additions and 9 deletions

View File

@ -63,6 +63,7 @@ import org.hibernate.query.sqm.tree.select.SqmSelection;
import org.hibernate.sql.results.internal.TupleMetadata;
import org.hibernate.sql.results.spi.ResultsConsumer;
import org.hibernate.sql.results.spi.SingleResultConsumer;
import org.hibernate.type.descriptor.java.JavaType;
import static org.hibernate.jpa.HibernateHints.HINT_CACHEABLE;
import static org.hibernate.jpa.HibernateHints.HINT_CACHE_MODE;
@ -278,15 +279,15 @@ public class SqmSelectionQueryImpl<R> extends AbstractSqmSelectionQuery<R>
else {
final SqmSelection<?> selection = selections.get( 0 );
if ( isSelectionAssignableToResultType( selection, expectedResultType ) ) {
return selection.getNodeJavaType().getJavaTypeClass();
final JavaType<?> nodeJavaType = selection.getNodeJavaType();
if ( nodeJavaType != null ) {
return nodeJavaType.getJavaTypeClass();
}
else {
// let's assume there's some
// way to instantiate it
}
// let's assume there's some way to instantiate it
return expectedResultType;
}
}
}
else if ( expectedResultType != null ) {
// assume we can repackage the tuple as
// the given type (worry about how later)

View File

@ -43,6 +43,7 @@ import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.metamodel.model.domain.internal.EntitySqmPathSource;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.BindableType;
import org.hibernate.query.IllegalQueryOperationException;
import org.hibernate.query.IllegalSelectQueryException;
import org.hibernate.query.Order;
@ -827,10 +828,15 @@ public class SqmUtil {
}
public static boolean isSelectionAssignableToResultType(SqmSelection<?> selection, Class<?> expectedResultType) {
if ( expectedResultType == null
|| selection != null && selection.getSelectableNode() instanceof SqmParameter ) {
if ( expectedResultType == null ) {
return true;
}
else if ( selection != null && selection.getSelectableNode() instanceof SqmParameter<?> sqmParameter ) {
final Class<?> anticipatedClass = sqmParameter.getAnticipatedType() != null ?
sqmParameter.getAnticipatedType().getBindableJavaType() :
null;
return anticipatedClass != null && expectedResultType.isAssignableFrom( anticipatedClass );
}
else if ( selection == null
|| !isHqlTuple( selection ) && selection.getSelectableNode().isCompoundSelection() ) {
return false;