iBatis 2.x <iterate> operator can't reference variable within fragments?

898 views
Skip to first unread message

Alex Sherwin

unread,
Jun 22, 2010, 10:13:08 AM6/22/10
to mybati...@googlegroups.com
We're seeing an issue where there is a sql fragment included inside of
a <iterate> tag. The error is a NumberFormatException, what it looks
like is that iBatis is not populating the index inside the [] brackets
in this scenario.

--- The error occurred in com/mycompany/SomeMapper.xml.
--- The error occurred while preparing the mapped statement for execution.
--- Check the SOME_NAMESPACE.SomeStatement.
--- Check the parameter map.
--- Cause: com.ibatis.common.beans.ProbeException: Error getting
ordinal list from JavaBean. Cause java.lang.NumberFormatException: For
input string: ""] SQL State [null] SQL Error Code [0]
Caused by: com.ibatis.common.beans.ProbeException: Error getting
ordinal list from JavaBean. Cause java.lang.NumberFormatException: For
input string: ""
at com.ibatis.common.beans.BaseProbe.getIndexedProperty(BaseProbe.java:86)
at com.ibatis.common.beans.ComplexBeanProbe.getProperty(ComplexBeanProbe.java:297)
at com.ibatis.common.beans.ComplexBeanProbe.getObject(ComplexBeanProbe.java:198)

We just updated to the latest 2.x branch (2.3.4) with no luck.

Is this a bug, and can we fix it locally?

--
Alexander Sherwin

Alex Sherwin

unread,
Jun 22, 2010, 11:02:07 AM6/22/10
to mybati...@googlegroups.com
Here is a small test case that demonstrates this.. this is against a
simple sys prop table.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="common">

<resultMap class="java.util.HashMap" id="result">
<result property="PROP_KEY" column="PROP_KEY" />
<result property="PROP_VALUE" column="PROP_VALUE" />
</resultMap>

<!-- THIS WORKS -->
<sql id="iterateColumnsFragment">
<iterate property="cols" conjunction=", ">
$cols[]$
</iterate>
</sql>

<select id="iterateSelect" resultMap="result" parameterClass="java.util.Map">
select
<include refid="iterateColumnsFragment" />
from
MYSCHEMA.TBL_SYS_PROPS
</select>

<!-- THIS DOESNT WORK -->
<sql id="iterateColumnOnlyFragment">
$cols[]$
</sql>

<select id="iterateSelectFragmented" resultMap="result"
parameterClass="java.util.Map">
select
<iterate property="cols" conjunction=", ">
<include refid="iterateColumnOnlyFragment" />
</iterate>
from
MYSCHEMA.TBL_SYS_PROPS
</select>

</sqlMap>

What i pass in for params is a HashMap with a key of "cols" with
contains a List<String> of "PROP_KEY" and "PROP_VALUE".

It should just iterate and select the columns PROP_KEY and PROP_VALUE
from the table.

The first scenario works, the second does not.

--
Alexander Sherwin

Poitras Christian

unread,
Jun 22, 2010, 1:40:29 PM6/22/10
to mybati...@googlegroups.com
From what I remember of the implementation of <iterate> tag, the problem is caused by the fact that $cols[]$ will looks for the parent <iterate> tag which is not included in the fragment.
Since there is no parent, no index can be found and this causes the exception your seeing.

I am not sure if it is possible to change iBATIS code for the iterate tag to support <include>.
I you want to do it, look at the code in these classes:
com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.IterateTagHandler
com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.IterateContext

Christian

Reply all
Reply to author
Forward
0 new messages