Skip to content

Commit 8bec334

Browse files
cigalysebersole
authored andcommitted
HHH-18322 Fix : when exact constructor is not found, try finding matching one
1 parent ab09c67 commit 8bec334

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

hibernate-core/src/main/java/org/hibernate/sql/results/internal/RowTransformerConstructorImpl.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
import org.hibernate.sql.results.spi.RowTransformer;
1010

1111
import java.lang.reflect.Constructor;
12+
import java.util.Arrays;
1213
import java.util.List;
1314

1415
import org.hibernate.query.sqm.SqmExpressible;
1516
import org.hibernate.query.sqm.tree.SqmExpressibleAccessor;
1617

18+
import static org.hibernate.query.sqm.tree.expression.Compatibility.areAssignmentCompatible;
19+
1720
/**
1821
* {@link RowTransformer} instantiating an arbitrary class
1922
*
@@ -31,7 +34,7 @@ public RowTransformerConstructorImpl(Class<T> type, TupleMetadata tupleMetadata)
3134
sig[i] = resolveElementJavaType( elements.get( i ) );
3235
}
3336
try {
34-
constructor = type.getDeclaredConstructor( sig );
37+
constructor = findMatchingConstructor( type, sig );
3538
constructor.setAccessible( true );
3639
}
3740
catch (Exception e) {
@@ -51,6 +54,38 @@ private static Class<?> resolveElementJavaType(TupleElement<?> element) {
5154
return element.getJavaType();
5255
}
5356

57+
private Constructor<T> findMatchingConstructor(
58+
Class<T> type,
59+
Class<?>[] sig) throws NoSuchMethodException {
60+
try {
61+
return type.getDeclaredConstructor( sig );
62+
}
63+
catch (NoSuchMethodException | SecurityException e) {
64+
constructor_loop:
65+
for ( final Constructor<?> constructor : type.getDeclaredConstructors() ) {
66+
final Class<?>[] parameterTypes = constructor.getParameterTypes();
67+
if ( parameterTypes.length == sig.length ) {
68+
for ( int i = 0; i < sig.length; i++ ) {
69+
final Class<?> parameterType = parameterTypes[i];
70+
final Class<?> argType = sig[i];
71+
final boolean assignmentCompatible;
72+
assignmentCompatible =
73+
argType == null && !parameterType.isPrimitive()
74+
|| areAssignmentCompatible(
75+
parameterType,
76+
argType
77+
);
78+
if ( !assignmentCompatible ) {
79+
continue constructor_loop;
80+
}
81+
}
82+
return (Constructor<T>) constructor;
83+
}
84+
}
85+
throw new NoSuchMethodException();
86+
}
87+
}
88+
5489
@Override
5590
public T transformRow(Object[] row) {
5691
try {

0 commit comments

Comments
 (0)