Skip to content

Unable to use composite key in nested query #725

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

Closed
ghost opened this issue Jul 1, 2016 · 3 comments
Closed

Unable to use composite key in nested query #725

ghost opened this issue Jul 1, 2016 · 3 comments

Comments

@ghost
Copy link

ghost commented Jul 1, 2016

MyBatis version

3.2.5+

Database vendor and version

Oracle 12c

Test case or example project

@Result(
        property="someProperty", 
        column="{param1Name=resultColumnNameForParam1, param2Name=resultColumnNameForParam2}",
        one=@One(select = "foo.MapperClass.mapperMethodName"))

@Select("select * from someTable where column1 = #{param1Name,jdbcType=INTEGER} and column2 = #{param2Name,jdbcType=INTEGER}")
int mapperMethodName(@Param("param1Name") int param1Name, @Param("param2Name") int param2Name)

Steps to reproduce

  1. Have a nested query that uses a mapper method taking multiple parameters.
  2. Use a composite key for column like:
    • "{param1Name=resultColumnNameForParam1, param2Name=resultColumnNameForParam2}"
    • or "param1Name=resultColumnNameForParam1, param2Name=resultColumnNameForParam2"

Expected result

Nested query with composite key works successfully.

Actual result

BindException is thrown "org.apache.ibatis.binding.BindingException: Parameter 'param1Name' not found. Available parameters are []"

Cause

This appears to have been caused by the fix for issue #135.

It makes the following change:
parameterType = ParamMap.class; // issue #135

whereas before that was:
parameterType = Map.class;

Map does not throw an error on retrieving a key that doesn't exist, while ParamMap does throw a BindException in this scenario.

This causes DefaultResultSetHandler to fail when it makes a call to prepareCompositeKeyParameter(). It constructs a MetaObject wrapping a ParamMap when it used to wrap a Map. This results in a MapWrapper being created by the MetaObject.

When prepareCompositeKeyParameter then makes a call to MetaObject.getSetterType() which calls MapWrapper.getSetterType(), the BindException is thrown.

In MapWrapper you can see the following code in getSetterType:

      if (map.get(name) != null) {
        return map.get(name).getClass();
      } else {
        return Object.class;
      }

The else can never be reached for a ParamMap because it will never return null, but instead throw a BindException.

@harawata
Copy link
Member

harawata commented Jul 1, 2016

Hi @pmlyon ,

Thank you for the report.
Just to clarify, have you tried this with 3.4.1?
It reminds me of #649 which was fixed in 3.4.1.

@ghost
Copy link
Author

ghost commented Jul 1, 2016

Ahh, this is a duplicate of #649. I just tried 3.4.1 and it worked, and I can see from the commit for #641 that it matched what I wrote above.

Thanks!

@harawata
Copy link
Member

harawata commented Jul 1, 2016

No problem :-)

@harawata harawata closed this as completed Jul 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant