Mybatis currently has the ability to match constructor args declared in mapper xml to constructors in bean classes using the parameter name. This mapping allows mybatis to:
- Determine which TypeHandler to use to get each column from the ResultSet [see DefaultResultSetHandler]
- Determine which Constructor to invoke with the List
Eg:
<resultMap id="account" type="com.company.Account">
<constructor>
<arg name="accountId" column="ACCOUNT_ID" />
<arg name="accountName" column="ACCOUNT_NAME" />
<arg name="accountType" column="ACCOUNT_TYPE" />
</constructor>
</resultMap>
My model classes do not contain the parameter name information (see ParamNameUtil.getParamNames(Constructor)) and I do not have control over these (so can't add annotations etc).
I'd like a change in mybatis to support the same behavior but with the following xml
<resultMap id="account" type="com.company.Account">
<constructor>
<arg column="ACCOUNT_ID" />
<arg column="ACCOUNT_NAME" />
<arg column="ACCOUNT_TYPE" />
</constructor>
</resultMap>
Unfortunately when I try this mybatis:
- defaults the javaType
for each argument to java.lang.Object
- uses the UnknownTypeHandler
to read values from the ResultSet
- tries to invoke the constructor com.company.Account(Object, Object, Object)
and fails with NoSuchMethodException
It would be great if mybatis could look for a single constructor with 3 arguments and determine the types from that. If there were more than one constructor with 3 arguments I think it would be fair for mybatis to throw an exception.
As a workaround I have to specifically tell mybatis the types but I feel this is repeating myself, and that mybatis should be able to use reflection to get the javaType
s
<resultMap id="account" type="com.company.Account">
<constructor>
<arg column="ACCOUNT_ID" javaType="java.lang.Long" />
<arg column="ACCOUNT_NAME" javaType="java.lang.String" />
<arg column="ACCOUNT_TYPE" javaType="java.lang.String" />
</constructor>
</resultMap>