Skip to content

Lookup constructor argument types based on index when arg name not provided #2618

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
uklance opened this issue Jul 15, 2022 · 0 comments
Open
Assignees
Milestone

Comments

@uklance
Copy link

uklance commented Jul 15, 2022

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 of values [see DefaultObjectFactory]

    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 javaTypes

    <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>
@epochcoder epochcoder self-assigned this Jan 3, 2025
epochcoder added a commit to epochcoder/mybatis-3 that referenced this issue Jan 3, 2025
…ry to determine the best matching constructor

- falls back to current behaviour if any ambiguity is detected
- remove setters from immutable `ResultMapping`
@epochcoder epochcoder added this to the 3.6.x milestone Jan 4, 2025
harawata pushed a commit to epochcoder/mybatis-3 that referenced this issue Jan 7, 2025
…ry to determine the best matching constructor

- falls back to current behaviour if any ambiguity is detected
- remove setters from immutable `ResultMapping`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants