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
