parameterMap not working as before

577 views
Skip to first unread message

Herman Bovens

unread,
Dec 15, 2010, 11:21:25 AM12/15/10
to mybati...@googlegroups.com
Hi,

I'm migrating from iBatis 2.x to MyBatis 3.03.
The project has hundreds of statements using <parameterMap>, so even though it is deprecated I would like to continue to use it for now, and gradually move to inline parameters.

However, I have two problems:

1) Most of the calls are to stored procedures, with a parameterMap of type="map", where the defined properties are used as keys in the map.   Using MyBatis 3, this doesn't seem to work anymore, for example:

<parameterMap id="getUsersByProjectParamMap" type="map">
    <parameter property="output" javaType="resultset" jdbcType="CURSOR" mode="OUT" resultMap="getUsersByProjectResultMap"/>
    <parameter property="ID_PROJECT" mode="IN" jdbcType="VARCHAR"/>
</parameterMap>

Results in this error:

    There is no getter for property named 'ID_PROJECT' in 'interface java.util.Map'

Is there a different way to use java.util.Map with the (deprecated) <parameterMap> ?


2) As I said I'd like to gradually move to inline maps, but want to keep the statements compatible so I only have to change the statements in the xml files, not in the java code (I have already changed the use of SqClientMap to SqlSessionFactory, but that was not a big change since it was abstracted).  I know I should be able to use parameterType="map" and access the values in the map using e.g.  #ID_PROJECT#.  However, the results of the stored procedures are currently mapped using result maps, and the mapped result is put back in the map using key "output", but I have no clue how to do that using inline parameters.

So could someone rewrite the following example in MyBatis 3 without <parameterMap>, but in a way that it can be called using a parameter of type java.util.Map containing the parameter values (just like in IBatis 2) ?

    <resultMap id="getUsersByProjectResultMap" class="com.example.User">
        <result property="id" column="ID" javaType="string"/>
        <result property="login" column="LOGIN" javaType="string"/>
        <result property="firstName" column="NAME_FIRST" javaType="string"/>
        <result property="middleName" column="NAME_MIDDLE" javaType="string"/>
        <result property="lastName" column="NAME_LAST" javaType="string"/>
    </resultMap>
   
    <parameterMap id="getUsersByProjectParamMap" class="map">
        <parameter property="output" javaType="resultset" jdbcType="ORACLECURSOR" mode="OUT" resultMap="getUsersByProjectResultMap"/>
        <parameter property="ID_PROJECT" mode="IN" jdbcType="VARCHAR"/>
    </parameterMap>
   
    <procedure id="getUsersByProject" parameterMap="getUsersByProjectParamMap">
        { ? = call pkgUsers.getbyidproject (ID_PROJECT => ?) }
    </procedure>

That should also help other people trying to migrate from iBatis 2.

Best regards,
Herman Bovens

Jeff Butler

unread,
Dec 15, 2010, 12:11:28 PM12/15/10
to mybati...@googlegroups.com
Hi Herman,

1. This is a bug. I'll work on a fix for it. Do you want to file an
issue in the google code project, or do you want me to do it?

2. Look here for examples of stored procedure call with Maps and
inline parameters:

http://mybatis.googlecode.com/svn/trunk/src/test/java/org/apache/ibatis/submitted/sptests/

Look specifically in the file SPMapper.xml and for the <select>
element with id="getNames"

Jeff Butler

Herman Bovens

unread,
Dec 15, 2010, 12:46:40 PM12/15/10
to mybati...@googlegroups.com
1. I've filed issue 203
2. Thanks, I'll look into it and get back if I have further questions

2010/12/15 Jeff Butler <jeffg...@gmail.com>

Jeff Butler

unread,
Dec 15, 2010, 12:50:07 PM12/15/10
to mybati...@googlegroups.com
I've got a fix for this - you caught me on a good day :) I'll commit
it shortly.

In the meantime, a workaround is to manually specify the javaType for
all <parameter> elements.

Jeff

Herman Bovens

unread,
Dec 15, 2010, 12:53:42 PM12/15/10
to mybati...@googlegroups.com
OK, I already have a question: in the text above the examples, I read:
"All IN, OUT, and INOUT parameters must be a part of the parameterType or parameterMap (discouraged)"

In the previous version the output parameter was not in the parameter map when calling, it was put there by iBatis.  E.g. a map value with key "output". Which value should I put in the parameter map for the "output" key then?

Thanks for helping out.

2010/12/15 Herman Bovens <herman...@gmail.com>

Jeff Butler

unread,
Dec 15, 2010, 1:13:10 PM12/15/10
to mybati...@googlegroups.com
I wrote that line without thinking of <parameterMap type="map">, or
parameterType="map". You are correct that OUT parameters will be
added to the map by MyBatis - you do not need to specify anything
before the call. The tests work that way and demonstrate that you
don't need to add anything to the map for output parameters, but I
agree the line is a bit confusing.

Jeff Butler

Herman Bovens

unread,
Dec 16, 2010, 8:53:52 AM12/16/10
to mybati...@googlegroups.com
Hi Jeff,

I was looking at "getNames" example in SPMapper.xml, and there it seems the output parameter of the stored procedure is just an integer, and the result of the procedure is mapped using the "nameResult" map.
However, in my case it is the output parameter itself that needs to be mapped (it has jdbcType="CURSOR").  Is there a way to specify the result map for an inline ouput parameter of type CURSOR ?

Thanks,
Herman

2010/12/15 Jeff Butler <jeffg...@gmail.com>

Herman Bovens

unread,
Dec 16, 2010, 9:38:15 AM12/16/10
to mybati...@googlegroups.com
After specifying the javaType the error at startup about the missing getter is gone, but when calling the procedure, I get this error:

 java.sql.SQLException: Missing IN or OUT parameter at index:: 1

As you can see in my original mail, there is one output parameter and one input parameter in the parameterMap, and there are 2 question marks in the statement, so I'd expect that to work (it did in iBatis 2.x).


2010/12/15 Jeff Butler <jeffg...@gmail.com>

Herman Bovens

unread,
Dec 16, 2010, 9:42:20 AM12/16/10
to mybati...@googlegroups.com
I thought I'd better show the exact xml that is not working:

<parameterMap id="getUsersByProjectParamMap" type="map">
    <parameter property="output" javaType="resultset" jdbcType="CURSOR" mode="OUT" resultMap="getUsersByProjectResultMap"/>
    <parameter property="ID_PROJECT" mode="IN" jdbcType="VARCHAR" javaType="string"/>
</parameterMap>
   
<select id="getUsersByProject" parameterMap="getUsersByProjectParamMap">
   
{ ? = call pkgUsers.getbyidproject (ID_PROJECT => ?) }
</select>
   


2010/12/16 Herman Bovens <herman...@gmail.com>

Herman Bovens

unread,
Dec 16, 2010, 10:36:32 AM12/16/10
to mybati...@googlegroups.com
OK, it seems this question was already answered on November 9 in this list, and I should be able to specify  resultMap=... in the inline output parameter for the cursor.

However, I did a quick test, and for a call like this:

<select id="getValues" parameterType="map">
    { #{output,jdbcType=CURSOR,javaType=resultset,mode=OUT,resultMap=valueResultMap} =
        call package.getValues (#{accountId,mode=IN,javaType=string}) }
</select>

I get the same error I get when using a parameterMap (see my other mail):


java.sql.SQLException: Missing IN or OUT parameter at index:: 1

The map of parameters I supply contains a value for the accountId parameter.

Could this be another bug?  Or am I doing something wrong?


2010/12/16 Herman Bovens <herman...@gmail.com>

Herman Bovens

unread,
Dec 16, 2010, 12:14:05 PM12/16/10
to mybati...@googlegroups.com
It seems I'm good at answering my own questions today :-)
For stored procedures the <select> tag needs an explicit statementType="CALLABLE" attribute.  The old <procedure> tag didn't require this, that's why it was missing in my case.

2010/12/16 Herman Bovens <herman...@gmail.com>
Reply all
Reply to author
Forward
0 new messages