Thanks!

And I bet that iBATIS 3.0 will.

Christian

-----Original Message-----
From: Jeff Butler [mailto:[email protected]]
Sent: Wednesday, February 18, 2009 3:46 PM
To: [email protected]
Subject: Re: Error iterating over set

Hi Christian,

This comes up somewhat regularly, so I looked into it a bit.  It turns out 
iBATIS is somewhat schizophrenic about Sets.

With dynamic SQL, there are two steps to processing the statement - first the 
actual SQL statement must be calculated and prepared based on the values in the 
parameter object, and then iBATIS must apply the parameter values to the 
prepared statement.  iBATIS can deal with a Set correctly in the first step, 
but not in the second.

I thought of a kludgy change that could be added fairly simply, but it is not 
optimal by any means - you would have to change the BaseProbe class to use the 
Set iterator to return an indexed value - something like this:

private Object getIndexedPropertyFromSet(Set set, int index) {
  Iterator iter = set.iterator();
  while (index > 0) {
    iter.next();
    index--;
  }

  return iter.next();
}


I think it's kind of ugly.  It's probably better to say that iBATIS doesn't 
really support Sets now.

Jeff Butler


On Wed, Feb 18, 2009 at 11:12 AM, Poitras Christian 
<[email protected]> wrote:
> I'm sorry, I didn't include the right exception. Here's the real stack
> trace and ParameterObject.
>
>
> public
>
> class ParameterObject {
>
> private Set idSet;
>
> public Set getIdSet() {
>
> return idSet;
>
> }
>
> }
>
>
>
> com.ibatis.common.jdbc.exception.NestedSQLException
>
> :
>
> --- The error occurred in test/IterateFailures_SqlMap.xml.
>
> --- The error occurred while preparing the mapped statement for execution.
>
> --- Check the IterateFailures.Test2.
>
> --- Check the parameter map.
>
> --- Cause:
>
> com.ibatis.common.beans.ProbeException: The 'idSet' property of the
> test.ParameterObject class is not a List or Array.
>
> at
> com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQuer
> yWithCallback(
>
> MappedStatement.java:204)
>
> at
> com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQuer
> yForList(
>
> MappedStatement.java:139)
>
> at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(
>
> SqlMapExecutorDelegate.java:567)
>
> at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(
>
> SqlMapExecutorDelegate.java:541)
>
> at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(
>
> SqlMapSessionImpl.java:118)
>
> at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(
>
> SqlMapClientImpl.java:94
> )
>
> at test.IterateTagTest.testIterateFailure2(
>
> IterateTagTest.java:162)
>
> at sun.reflect.NativeMethodAccessorImpl.invoke0(
>
> Native Method)
>
> at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
>
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>
> at java.lang.reflect.Method.invoke(Unknown Source)
>
> at junit.framework.TestCase.runTest(
>
> TestCase.java:168)
>
> at junit.framework.TestCase.runBare(
>
> TestCase.java:134)
>
> at junit.framework.TestResult$1.protect(
>
> TestResult.java:110)
>
> at junit.framework.TestResult.runProtected(
>
> TestResult.java:128)
>
> at junit.framework.TestResult.run(
>
> TestResult.java:113)
>
> at junit.framework.TestCase.run(
>
> TestCase.java:124)
>
> at junit.framework.TestSuite.runTest(
>
> TestSuite.java:232)
>
> at junit.framework.TestSuite.run(
>
> TestSuite.java:227)
>
> at org.junit.internal.runners.OldTestClassRunner.run(
>
> OldTestClassRunner.java:76)
>
> at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(
>
> JUnit4TestReference.java:38)
>
> at org.eclipse.jdt.internal.junit.runner.TestExecution.run(
>
> TestExecution.java:38)
>
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(
>
> RemoteTestRunner.java:460)
>
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(
>
> RemoteTestRunner.java:673)
>
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(
>
> RemoteTestRunner.java:386)
>
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(
>
> RemoteTestRunner.java:196)
>
> Caused by:
>
> com.ibatis.common.beans.ProbeException: The 'idSet' property of the
> test.ParameterObject class is not a List or Array.
>
> at com.ibatis.common.beans.BaseProbe.getIndexedProperty(
>
> BaseProbe.java:80)
>
> at com.ibatis.common.beans.ComplexBeanProbe.getProperty(
>
> ComplexBeanProbe.java:297)
>
> at com.ibatis.common.beans.ComplexBeanProbe.getObject(
>
> ComplexBeanProbe.java:198)
>
> at com.ibatis.common.beans.GenericProbe.getObject(
>
> GenericProbe.java:74
> )
>
> at
> com.ibatis.sqlmap.engine.accessplan.ComplexAccessPlan.getProperties(
>
> ComplexAccessPlan.java:41)
>
> at com.ibatis.sqlmap.engine.exchange.JavaBeanDataExchange.getData(
>
> JavaBeanDataExchange.java:91)
>
> at
> com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap.getParameterOb
> jectValues(
>
> ParameterMap.java:133)
>
> at
> com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQuer
> yWithCallback(
>
> MappedStatement.java:181)
>
> ... 25 more
>
> ________________________________
> From: Poitras Christian [mailto:[email protected]]
> Sent: Wednesday, February 18, 2009 12:02 PM
> To: '[email protected]'
> Subject: Error iterating over set
>
> Hi,
>
> In iBATIS documentation, it is indicated that <iterate> tag works over
> any type of java.util.Collection.
> When I try to iterate over a Set with iBATIS 2.3.4, I get an exception
> (see end of email).
>
> Is it required to give <iterate> tag a list?
>
> Christian
>
>
> com.ibatis.common.jdbc.exception.NestedSQLException
>
> :
>
> --- The error occurred in test/IterateFailures_SqlMap.xml.
>
> --- The error occurred while preparing the mapped statement for execution.
>
> --- Check the IterateFailures.Test1.
>
> --- Check the parameter map.
>
> --- Cause:
>
> com.ibatis.common.beans.ProbeException: Error getting ordinal list
> from JavaBean. Cause java.lang.NumberFormatException: For input string: ""
>
> at
> com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQuer
> yWithCallback(
>
> MappedStatement.java:204)
>
> at
> com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQuer
> yForList(
>
> MappedStatement.java:139)
>
> at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(
>
> SqlMapExecutorDelegate.java:567)
>
> at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(
>
> SqlMapExecutorDelegate.java:541)
>
> at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(
>
> SqlMapSessionImpl.java:118)
>
> at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(
>
> SqlMapClientImpl.java:94)
>
> at test.IterateTagTest.testIterateFailure1(
>
> IterateTagTest.java:126)
>
> at sun.reflect.NativeMethodAccessorImpl.invoke0(
>
> Native Method)
>
> at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
>
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>
> at java.lang.reflect.Method.invoke(Unknown Source)
>
> at junit.framework.TestCase.runTest(
>
> TestCase.java:168)
>
> at junit.framework.TestCase.runBare(
>
> TestCase.java:134)
>
> at junit.framework.TestResult$1.protect(
>
> TestResult.java:110)
>
> at junit.framework.TestResult.runProtected(
>
> TestResult.java:128)
>
> at junit.framework.TestResult.run(
>
> TestResult.java:113)
>
> at junit.framework.TestCase.run(
>
> TestCase.java:124)
>
> at junit.framework.TestSuite.runTest(
>
> TestSuite.java:232)
>
> at junit.framework.TestSuite.run(
>
> TestSuite.java:227)
>
> at org.junit.internal.runners.OldTestClassRunner.run(
>
> OldTestClassRunner.java:76)
>
> at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(
>
> JUnit4TestReference.java:38)
>
> at org.eclipse.jdt.internal.junit.runner.TestExecution.run(
>
> TestExecution.java:38)
>
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(
>
> RemoteTestRunner.java:460)
>
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(
>
> RemoteTestRunner.java:673)
>
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(
>
> RemoteTestRunner.java:386)
>
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(
>
> RemoteTestRunner.java:196)
>
> 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)
>
> at com.ibatis.common.beans.GenericProbe.getObject(
>
> GenericProbe.java:74)
>
> at
> com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.IterateTagHandle
> r.doStartFragment(
>
> IterateTagHandler.java:47)
>
> at
> com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChi
> ldren(
>
> DynamicSql.java:156)
>
> at
> com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChi
> ldren(
>
> DynamicSql.java:159)
>
> at
> com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChi
> ldren(
>
> DynamicSql.java:98)
>
> at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.process(
>
> DynamicSql.java:78)
>
> at
> com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.getParameterMa
> p(
>
> DynamicSql.java:60)
>
> at
> com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQuer
> yWithCallback(
>
> MappedStatement.java:172)
>
> ... 25 more
>
> Caused by:
>
> java.lang.NumberFormatException: For input string: ""
>
> at java.lang.NumberFormatException.forInputString(Unknown Source)
>
> at java.lang.Integer.parseInt(Unknown Source)
>
> at java.lang.Integer.parseInt(Unknown Source)
>
> at com.ibatis.common.beans.BaseProbe.getIndexedProperty(
>
> BaseProbe.java:51)
>
> ... 35 more

Reply via email to