13
13
14
14
import org .hibernate .query .sqm .SqmExpressible ;
15
15
import org .hibernate .query .sqm .tree .SqmExpressibleAccessor ;
16
+ import org .hibernate .type .spi .TypeConfiguration ;
16
17
17
- import static org .hibernate .query .sqm .tree .expression .Compatibility .areAssignmentCompatible ;
18
+ import static java .util .stream .Collectors .toList ;
19
+ import static org .hibernate .sql .results .graph .instantiation .internal .InstantiationHelper .findMatchingConstructor ;
18
20
19
21
/**
20
22
* {@link RowTransformer} instantiating an arbitrary class
@@ -25,25 +27,25 @@ public class RowTransformerConstructorImpl<T> implements RowTransformer<T> {
25
27
private final Class <T > type ;
26
28
private final Constructor <T > constructor ;
27
29
28
- public RowTransformerConstructorImpl (Class <T > type , TupleMetadata tupleMetadata ) {
30
+ public RowTransformerConstructorImpl (
31
+ Class <T > type ,
32
+ TupleMetadata tupleMetadata ,
33
+ TypeConfiguration typeConfiguration ) {
29
34
this .type = type ;
30
35
final List <TupleElement <?>> elements = tupleMetadata .getList ();
31
- final Class <?>[] sig = new Class [elements .size ()];
32
- for (int i = 0 ; i < elements .size (); i ++) {
33
- sig [i ] = resolveElementJavaType ( elements .get ( i ) );
34
- }
35
- if ( sig .length == 1 && sig [0 ] == null ) {
36
+ final List <Class <?>> argumentTypes = elements .stream ()
37
+ .map ( RowTransformerConstructorImpl ::resolveElementJavaType )
38
+ .collect ( toList () );
39
+ if ( argumentTypes .size () == 1 && argumentTypes .get ( 0 ) == null ) {
36
40
// Can not (properly) resolve constructor for single null element
37
41
throw new InstantiationException ( "Cannot instantiate query result type, argument types are unknown " , type );
38
42
}
39
- try {
40
- constructor = findMatchingConstructor ( type , sig );
41
- constructor .setAccessible ( true );
42
- }
43
- catch (Exception e ) {
44
- //TODO try again with primitive types
45
- throw new InstantiationException ( "Cannot instantiate query result type " , type , e );
43
+
44
+ constructor = findMatchingConstructor ( type , argumentTypes , typeConfiguration );
45
+ if ( constructor == null ) {
46
+ throw new InstantiationException ( "Cannot instantiate query result type, found no matching constructor" , type );
46
47
}
48
+ constructor .setAccessible ( true );
47
49
}
48
50
49
51
private static Class <?> resolveElementJavaType (TupleElement <?> element ) {
@@ -57,36 +59,6 @@ private static Class<?> resolveElementJavaType(TupleElement<?> element) {
57
59
return element .getJavaType ();
58
60
}
59
61
60
- private Constructor <T > findMatchingConstructor (Class <T > type , Class <?>[] sig ) throws Exception {
61
- try {
62
- return type .getDeclaredConstructor ( sig );
63
- }
64
- catch (NoSuchMethodException | SecurityException e ) {
65
- constructor_loop :
66
- for ( final Constructor <?> constructor : type .getDeclaredConstructors () ) {
67
- final Class <?>[] parameterTypes = constructor .getParameterTypes ();
68
- if ( parameterTypes .length == sig .length ) {
69
- for ( int i = 0 ; i < sig .length ; i ++ ) {
70
- final Class <?> parameterType = parameterTypes [i ];
71
- final Class <?> argType = sig [i ];
72
- final boolean assignmentCompatible ;
73
- assignmentCompatible =
74
- argType == null && !parameterType .isPrimitive ()
75
- || areAssignmentCompatible (
76
- parameterType ,
77
- argType
78
- );
79
- if ( !assignmentCompatible ) {
80
- continue constructor_loop ;
81
- }
82
- }
83
- return (Constructor <T >) constructor ;
84
- }
85
- }
86
- throw e ;
87
- }
88
- }
89
-
90
62
@ Override
91
63
public T transformRow (Object [] row ) {
92
64
try {
0 commit comments