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 46293dbde4
commit cda7dad83b
2 changed files with 17 additions and 9 deletions

View File

@ -64,6 +64,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;
@ -277,15 +278,15 @@ public class SqmSelectionQueryImpl<R> extends AbstractSqmSelectionQuery<R>
return Object[].class;
}
else {
final SqmSelection<?> selection = selections.get(0);
final SqmSelection<?> selection = selections.get( 0 );
if ( isSelectionAssignableToResultType( selection, expectedResultType ) ) {
return selection.getNodeJavaType().getJavaTypeClass();
}
else {
// let's assume there's some
// way to instantiate it
return expectedResultType;
final JavaType<?> nodeJavaType = selection.getNodeJavaType();
if ( nodeJavaType != null ) {
return nodeJavaType.getJavaTypeClass();
}
}
// let's assume there's some way to instantiate it
return expectedResultType;
}
}
else if ( expectedResultType != null ) {

View File

@ -46,6 +46,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;
@ -853,10 +854,16 @@ 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<?> ) {
final SqmParameter<?> sqmParameter = (SqmParameter<?>) selection.getSelectableNode();
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;