HHH-18322 Fix : when exact constructor is not found, try finding matching one

This commit is contained in:
Čedomir Igaly 2024-06-24 11:03:23 +02:00 committed by Steve Ebersole
parent ab09c672a3
commit 8bec334ab2
1 changed files with 36 additions and 1 deletions

View File

@ -9,11 +9,14 @@ import org.hibernate.InstantiationException;
import org.hibernate.sql.results.spi.RowTransformer;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.List;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.query.sqm.tree.SqmExpressibleAccessor;
import static org.hibernate.query.sqm.tree.expression.Compatibility.areAssignmentCompatible;
/**
* {@link RowTransformer} instantiating an arbitrary class
*
@ -31,7 +34,7 @@ public class RowTransformerConstructorImpl<T> implements RowTransformer<T> {
sig[i] = resolveElementJavaType( elements.get( i ) );
}
try {
constructor = type.getDeclaredConstructor( sig );
constructor = findMatchingConstructor( type, sig );
constructor.setAccessible( true );
}
catch (Exception e) {
@ -51,6 +54,38 @@ public class RowTransformerConstructorImpl<T> implements RowTransformer<T> {
return element.getJavaType();
}
private Constructor<T> findMatchingConstructor(
Class<T> type,
Class<?>[] sig) throws NoSuchMethodException {
try {
return type.getDeclaredConstructor( sig );
}
catch (NoSuchMethodException | SecurityException e) {
constructor_loop:
for ( final Constructor<?> constructor : type.getDeclaredConstructors() ) {
final Class<?>[] parameterTypes = constructor.getParameterTypes();
if ( parameterTypes.length == sig.length ) {
for ( int i = 0; i < sig.length; i++ ) {
final Class<?> parameterType = parameterTypes[i];
final Class<?> argType = sig[i];
final boolean assignmentCompatible;
assignmentCompatible =
argType == null && !parameterType.isPrimitive()
|| areAssignmentCompatible(
parameterType,
argType
);
if ( !assignmentCompatible ) {
continue constructor_loop;
}
}
return (Constructor<T>) constructor;
}
}
throw new NoSuchMethodException();
}
}
@Override
public T transformRow(Object[] row) {
try {