Description
MyBatis version
3.5.11
Steps to reproduce
class MyType {
final String computed;
public MyType(Integer i) {
this.computed = i + "";
}
}
@Select("...")
@ConstructorArgs({ @Arg(column = "...", name = "i") })
List<MyType> select();
Expected result
MyBatis should understand that i
is expected to be of type Integer
given it's the type of the matching argument in the constructor.
Actual result
I get in the logs:
Found a constructor with arg names [i], but the type of 'i' did not match. Specified: [java.lang.Object] Declared: [java.lang.Integer]
I believe this is due to the fact that MapperAnnotationBuilder#applyConstructorArgs
calls MapperBuilderAssistant#buildResultMapping
, which tries to resolve the Java type by looking at the class' fields, instead of by looking at the constructor args as one could think given @ConstructorArgs
is used.
In my example, because MyType
doesn't have a field named i
, only a constructor arg, then it doesn't successfully resolve the type of i
and defaults to Object
(see MapperBuilderAssistant#resolveResultJavaType
).
I believe when @ConstructorArgs
is used, then implicit type resolution should be run against the constructor arguments.
Workaround
Explicitly specify the Java type to use:
@Arg(column = "i", name = "i", javaType = Integer.class)
Side notes
Relates to #2207, although not exactly the same case I believe.