ArchiveOrangemail archive

dev.ibatis.apache.org


(List home) (Recent threads) (3 other Apache iBATIS lists)

Subscription Options

  • RSS or Atom: Read-only subscription using a browser or aggregator. This is the recommended way if you don't need to send messages to the list. You can learn more about feed syndication and clients here.
  • Conventional: All messages are delivered to your mail address, and you can reply. To subscribe, send an email to the list's subscribe address with "subscribe" in the subject line, or visit the list's homepage here.
  • This list contains about 3,674 messages, beginning Jun 2005
  • This list doesn't seem to be active
Report the Spam
This button sends a spam report to the moderator. Please use it sparingly. For other removal requests, read this.
Are you sure? yes no

Created: (IBATIS-281) Nested iterate tags does not work

Ad
Christian Poitras (JIRA) 1144074269Mon, 03 Apr 2006 14:24:29 +0000 (UTC)
Nested iterate tags does not work
Christian Poitras (JIRA) 1144077770Mon, 03 Apr 2006 15:22:50 +0000 (UTC)
[ http://issues.apache.org/jira/browse/IBATIS-2... ] 

Christian Poitras commented on IBATIS-281:
------------------------------------------

In the description, the exception is caused because BeanProbe tries to call the following method from parameter class.
getList(new java.Integer(""))

It generates the error provided in the description.
In fact the property accessed by the following nested iterate tags is as follow.
<iterate property="list">
  <iterate property="list[].list">
    #list[].list[].property#
  </iterate>
</iterate>

The property accessed is "list[].list[0].property" in the first iteration (no other iterations are made).
> Nested iterate tags does not work > --------------------------------- > > Key: IBATIS-281 > URL: http://issues.apache.org/jira/browse/IBATIS-2... > Project: iBatis for Java > Type: Bug > Components: SQL Maps > Versions: 2.1.7 > Reporter: Christian Poitras > Attachments: ConditionalTagHandler.java, DynamicSql.java, IterateTagHandler.java > > No nested iterate tags work. The second iterate tag is not supported and produces the following error. > java.lang.NumberFormatException: For input string: "" > at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) > at java.lang.Integer.parseInt(Integer.java:489) > at java.lang.Integer.parseInt(Integer.java:518) > at com.ibatis.common.beans.BaseProbe.getIndexedProperty(BaseProbe.java:51) > at com.ibatis.common.beans.ComplexBeanProbe.getProperty(ComplexBeanProbe.java:297) > at com.ibatis.common.beans.ComplexBeanProbe.getObject(ComplexBeanProbe.java:188) > at com.ibatis.common.beans.GenericProbe.getObject(GenericProbe.java:76) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.IterateTagHandler.doStartFragment(IterateTagHandler.java:34) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:157) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:160) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:99) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.process(DynamicSql.java:79) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.getParameterMap(DynamicSql.java:61) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:156) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForList(GeneralStatement.java:123) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:610) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:584) > at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:101) > at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:78) > at com.ibatis.dao.client.template.SqlMapDaoTemplate.queryForList(SqlMapDaoTemplate.java:203) > at ca.qc.ircm.lana.persistence.sqlmapdao.SpotSqlMapDao.getSpotsInter(SpotSqlMapDao.java:159) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at com.ibatis.dao.engine.impl.DaoProxy.invoke(DaoProxy.java:72) > at $Proxy14.getSpotsInter(Unknown Source) > at ca.qc.ircm.lana.service.InterpretationService.getSpotsInter(InterpretationService.java:82) > at TEST.testInterpretation.main(testInterpretation.java:111) > It seems the second iterate tag cannot have a property of this type. > <iterate property="list" > > <iterate property="list[].list"> > <iterate> > </iterate> > On the nested iterate, SQL Maps does not add the number in attribute property "list[].list" and tries to call a getter for parameterClass.getList[]() and this is not allowed and produces the error. > This could be prevented in the IterateTagHandler class (doStartFragment method) by adding code that replaces "[]" in the property attribute by values of IterateContext that are parents of the current tag (for multiple nested iterate). > Other code would need to be updated since using a property in the second list also causes SQL Map to crash even it IterateTagHandler is patched. > <iterate property="list" > > <iterate property="list[].list"> > #list[].list[].someProperty# > <iterate> > </iterate> > I produced a patch that can correct the problem. I will include it in a future message.
Christian Poitras (JIRA) 1146841209Fri, 05 May 2006 15:00:09 +0000 (UTC)
[ http://issues.apache.org/jira/browse/IBATIS-2... ] 

Christian Poitras commented on IBATIS-281:
------------------------------------------

The best way to correct this issue is to change the IterateContext class to add a "public IterateContext getParent()" method.
Or the SqlTagContext class could be changed to add a "public IterateContext getIterateContext(int i)" or a "public IterateContext getParentIterateContext(IterateContext ic)".

Another way to fix this in a convenient way would be to allow access to any parent tag we want based on the JSP model of java. The method "public static final Tag findAncestorWithClass(Tag from, Class klass)" from class javax.servlet.jsp.tagext.TagSupport gives a good way to search for any parent class we want to look at and will simplify my patch and make it readable for most people.
This part of code from IterateTagHandler could be simplified since it only searches for the parent IterateContext.

For example, the patch.
                  // Add iteration number to property.
                  Object parentContext = ctx.getAttribute(parentTag);
                  while (!(parentContext instanceof IterateContext)) {
                      parentTag = parentTag.getParent();
                      parentContext = ctx.getAttribute(parentTag);
                  }
                  IterateContext parentIterateContext = (IterateContext) parentContext;


could be changed to:
                  // Add iteration number to property.
                  IterateContext parentIterate = ctx.getAttribute(parentIterate);


Also a utility class could handle the problem of adding the value of many IterateContext to any property value of any tags or any replacement value contained in a sql request (like #list[].id#) by executing the code in the patch in only one place.

Considering this, it would make correcting this bug in any very easy since we could also handle the current problem of my patch which is having the following tag <isEqual property="list[].list[3].list[].id" value="someValue"/>. It throws an exception when processing the "list[3]" part. By putting this logic in one place, we could check if a number is already between the "[]" and skip the corresponding IterateContext (if it is linked to an iterateContext).
But we must be carreful that the following example will not cause a problem, so we can't automatically skip an IterateContext without first checking if the "[]" is linked to an iterate tag.
<select>
  <iterate property="list">
    <iterate property="list[].list[3].list">
    </iterate>
  </iterate>
</select>
> Nested iterate tags does not work > --------------------------------- > > Key: IBATIS-281 > URL: http://issues.apache.org/jira/browse/IBATIS-2... > Project: iBatis for Java > Type: Bug > Components: SQL Maps > Versions: 2.1.7 > Reporter: Christian Poitras > Attachments: ConditionalTagHandler.java, DynamicSql.java, IterateTagHandler.java > > No nested iterate tags work. The second iterate tag is not supported and produces the following error. > java.lang.NumberFormatException: For input string: "" > at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) > at java.lang.Integer.parseInt(Integer.java:489) > at java.lang.Integer.parseInt(Integer.java:518) > at com.ibatis.common.beans.BaseProbe.getIndexedProperty(BaseProbe.java:51) > at com.ibatis.common.beans.ComplexBeanProbe.getProperty(ComplexBeanProbe.java:297) > at com.ibatis.common.beans.ComplexBeanProbe.getObject(ComplexBeanProbe.java:188) > at com.ibatis.common.beans.GenericProbe.getObject(GenericProbe.java:76) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.IterateTagHandler.doStartFragment(IterateTagHandler.java:34) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:157) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:160) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:99) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.process(DynamicSql.java:79) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.getParameterMap(DynamicSql.java:61) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:156) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForList(GeneralStatement.java:123) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:610) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:584) > at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:101) > at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:78) > at com.ibatis.dao.client.template.SqlMapDaoTemplate.queryForList(SqlMapDaoTemplate.java:203) > at ca.qc.ircm.lana.persistence.sqlmapdao.SpotSqlMapDao.getSpotsInter(SpotSqlMapDao.java:159) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at com.ibatis.dao.engine.impl.DaoProxy.invoke(DaoProxy.java:72) > at $Proxy14.getSpotsInter(Unknown Source) > at ca.qc.ircm.lana.service.InterpretationService.getSpotsInter(InterpretationService.java:82) > at TEST.testInterpretation.main(testInterpretation.java:111) > It seems the second iterate tag cannot have a property of this type. > <iterate property="list" > > <iterate property="list[].list"> > <iterate> > </iterate> > On the nested iterate, SQL Maps does not add the number in attribute property "list[].list" and tries to call a getter for parameterClass.getList[]() and this is not allowed and produces the error. > This could be prevented in the IterateTagHandler class (doStartFragment method) by adding code that replaces "[]" in the property attribute by values of IterateContext that are parents of the current tag (for multiple nested iterate). > Other code would need to be updated since using a property in the second list also causes SQL Map to crash even it IterateTagHandler is patched. > <iterate property="list" > > <iterate property="list[].list"> > #list[].list[].someProperty# > <iterate> > </iterate> > I produced a patch that can correct the problem. I will include it in a future message.
Jeff Butler (JIRA) 1147791457Tue, 16 May 2006 14:57:37 +0000 (UTC)
[ http://issues.apache.org/jira/browse/IBATIS-2... ] 

Jeff Butler commented on IBATIS-281:
------------------------------------

I'd like to use this issue as a catch all issue for problems with the iterate tag.  Please feel free to add additional use cases that fail if you find them (I am already aware of IBATIS-293 so no need to repeat that here).

Christian - thanks for your work on this issue!  Could you please elaborate on the comment you made 05/May/2006?  Are you proposing a different fix than your original patches, or is the comment related to another issue?  I'm trying not to duplicate all your research.

My status so far...

I've writen a set of test cases that demonstrate various failures of the iterate tag.  The general classes of failures are these:

1. Nested iterates where the nested iterate tags are dependant on the parent tags
2. Nested iterates where the nested iterate tags are independant of the parent tags (i.e. iterating over two seperate properties - kind of like nested for loops)
3. Conditional tags inside iterates fail if the the first element of the iterate does not meet the condition

Christian's patches solve problem #1 as far as I can tell, but not the others.  I believe I have a fix for #3, and I've not started to figure out why #2 doesn't work yet.
> Nested iterate tags does not work > --------------------------------- > > Key: IBATIS-281 > URL: http://issues.apache.org/jira/browse/IBATIS-2... > Project: iBatis for Java > Type: Bug > Components: SQL Maps > Versions: 2.1.7 > Reporter: Christian Poitras > Assignee: Jeff Butler > Attachments: ConditionalTagHandler.java, DynamicSql.java, IterateTagHandler.java > > No nested iterate tags work. The second iterate tag is not supported and produces the following error. > java.lang.NumberFormatException: For input string: "" > at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) > at java.lang.Integer.parseInt(Integer.java:489) > at java.lang.Integer.parseInt(Integer.java:518) > at com.ibatis.common.beans.BaseProbe.getIndexedProperty(BaseProbe.java:51) > at com.ibatis.common.beans.ComplexBeanProbe.getProperty(ComplexBeanProbe.java:297) > at com.ibatis.common.beans.ComplexBeanProbe.getObject(ComplexBeanProbe.java:188) > at com.ibatis.common.beans.GenericProbe.getObject(GenericProbe.java:76) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.IterateTagHandler.doStartFragment(IterateTagHandler.java:34) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:157) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:160) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:99) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.process(DynamicSql.java:79) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.getParameterMap(DynamicSql.java:61) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:156) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForList(GeneralStatement.java:123) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:610) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:584) > at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:101) > at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:78) > at com.ibatis.dao.client.template.SqlMapDaoTemplate.queryForList(SqlMapDaoTemplate.java:203) > at ca.qc.ircm.lana.persistence.sqlmapdao.SpotSqlMapDao.getSpotsInter(SpotSqlMapDao.java:159) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at com.ibatis.dao.engine.impl.DaoProxy.invoke(DaoProxy.java:72) > at $Proxy14.getSpotsInter(Unknown Source) > at ca.qc.ircm.lana.service.InterpretationService.getSpotsInter(InterpretationService.java:82) > at TEST.testInterpretation.main(testInterpretation.java:111) > It seems the second iterate tag cannot have a property of this type. > <iterate property="list" > > <iterate property="list[].list"> > <iterate> > </iterate> > On the nested iterate, SQL Maps does not add the number in attribute property "list[].list" and tries to call a getter for parameterClass.getList[]() and this is not allowed and produces the error. > This could be prevented in the IterateTagHandler class (doStartFragment method) by adding code that replaces "[]" in the property attribute by values of IterateContext that are parents of the current tag (for multiple nested iterate). > Other code would need to be updated since using a property in the second list also causes SQL Map to crash even it IterateTagHandler is patched. > <iterate property="list" > > <iterate property="list[].list"> > #list[].list[].someProperty# > <iterate> > </iterate> > I produced a patch that can correct the problem. I will include it in a future message.
Christian Poitras (JIRA) 1147806823Tue, 16 May 2006 19:13:43 +0000 (UTC)
[ http://issues.apache.org/jira/browse/IBATIS-2... ] 

Christian Poitras commented on IBATIS-281:
------------------------------------------

I think I was not clear in my other comment. The comment was related to my patch. The patch I proposed has some major programming problems and I sent them to give a starting point.
The first problem is the duplicate of the added code in classes ConditonalTagHandler and IterateTagHandler. The added code part should be removed from these classes and put in one simple class. I suggest the IterateContext that could handle the replacing of values in another tag property value. The TagHandlers could then call "parentIterateContextInstance.processProperty(currentTag.getProperty());" when there is a "[]" in the property.
The code in IterateContext would be almost he same as my code, since my code will not work in this specific example.
<statement>
<iterate property="list">
<iterate property="list[3].list">
</iterate>
</iterate>
</statement>
The reason is that my code will try add the index value of the first iterate tag even if the value is specified (here, the value is 3). This will generate an exception.
To correct the problem, we only need to check if the caracter after the "[" is a "]". If this is not the case, skip the current iterate context and call it's parent "processProperty" method if there is still an unprocessed "[" in the property.
We also need a getParent() method in IterateContext that will return it's parent IterateContext.
I suggest to add this king of code for the processProperty() method.
              public method processProperty(String tagPropety) {
                    int index = lastIndexOf("[");
                    int propertyIndex = lastIndexOf(this.getProperty);
                    if () {
              }

The same problem applies to ConditionalTagHandler. Jeff, I'm sorry I didn't see the problem #3 you are talking about. Can you show me an exemple where this kind of bug happens? I may have already a part of the solution for the problem.
Maybe the problem can be solved by adding this code to ConditionalTagHandler doStartFragment() method.
              // Increase index if the first tag is another iterate.
              IterateContext itCtx = ctx.peekIterateContext();
              if(null != itCtx && itCtx.isAllowNext()){
                  itCtx.next();
                  itCtx.setAllowNext(false);
                  if(!itCtx.hasNext()) {
                      itCtx.setFinal(true);
                  }
              }


The DynamicSql class could also make a call to "iterateContext.processProperty();" to replace the body content replacing my code.

These changes will make the patch easier to maintain for future development.


For problem #2, applying these changes could result in correcting the bug... I believe my patch needs to have
> Nested iterate tags does not work > --------------------------------- > > Key: IBATIS-281 > URL: http://issues.apache.org/jira/browse/IBATIS-2... > Project: iBatis for Java > Type: Bug > Components: SQL Maps > Versions: 2.1.7 > Reporter: Christian Poitras > Assignee: Jeff Butler > Attachments: ConditionalTagHandler.java, DynamicSql.java, IterateTagHandler.java > > No nested iterate tags work. The second iterate tag is not supported and produces the following error. > java.lang.NumberFormatException: For input string: "" > at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) > at java.lang.Integer.parseInt(Integer.java:489) > at java.lang.Integer.parseInt(Integer.java:518) > at com.ibatis.common.beans.BaseProbe.getIndexedProperty(BaseProbe.java:51) > at com.ibatis.common.beans.ComplexBeanProbe.getProperty(ComplexBeanProbe.java:297) > at com.ibatis.common.beans.ComplexBeanProbe.getObject(ComplexBeanProbe.java:188) > at com.ibatis.common.beans.GenericProbe.getObject(GenericProbe.java:76) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.IterateTagHandler.doStartFragment(IterateTagHandler.java:34) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:157) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:160) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:99) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.process(DynamicSql.java:79) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.getParameterMap(DynamicSql.java:61) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:156) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForList(GeneralStatement.java:123) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:610) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:584) > at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:101) > at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:78) > at com.ibatis.dao.client.template.SqlMapDaoTemplate.queryForList(SqlMapDaoTemplate.java:203) > at ca.qc.ircm.lana.persistence.sqlmapdao.SpotSqlMapDao.getSpotsInter(SpotSqlMapDao.java:159) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at com.ibatis.dao.engine.impl.DaoProxy.invoke(DaoProxy.java:72) > at $Proxy14.getSpotsInter(Unknown Source) > at ca.qc.ircm.lana.service.InterpretationService.getSpotsInter(InterpretationService.java:82) > at TEST.testInterpretation.main(testInterpretation.java:111) > It seems the second iterate tag cannot have a property of this type. > <iterate property="list" > > <iterate property="list[].list"> > <iterate> > </iterate> > On the nested iterate, SQL Maps does not add the number in attribute property "list[].list" and tries to call a getter for parameterClass.getList[]() and this is not allowed and produces the error. > This could be prevented in the IterateTagHandler class (doStartFragment method) by adding code that replaces "[]" in the property attribute by values of IterateContext that are parents of the current tag (for multiple nested iterate). > Other code would need to be updated since using a property in the second list also causes SQL Map to crash even it IterateTagHandler is patched. > <iterate property="list" > > <iterate property="list[].list"> > #list[].list[].someProperty# > <iterate> > </iterate> > I produced a patch that can correct the problem. I will include it in a future message.
Christian Poitras (JIRA) 1147807062Tue, 16 May 2006 19:17:42 +0000 (UTC)
[ http://issues.apache.org/jira/browse/IBATIS-2... ] 

Christian Poitras commented on IBATIS-281:
------------------------------------------

I accendly pressed enter while writting my other comment. Please ignore it.


I think I was not clear in my other comment. The comment was related to my patch. The patch I proposed has some major programming problems and I sent them to give a starting point.
The first problem is the duplicate of the added code in classes ConditonalTagHandler and IterateTagHandler. The added code part should be removed from these classes and put in one simple class. I suggest the IterateContext that could handle the replacing of values in another tag property value. The TagHandlers could then call "parentIterateContextInstance.processProperty(currentTag.getProperty());" when there is a "[]" in the property.
The code in IterateContext would be almost he same as my code, since my code will not work in this specific example.
<statement>
<iterate property="list">
<iterate property="list[3].list">
</iterate>
</iterate>
</statement>
The reason is that my code will try add the index value of the first iterate tag even if the value is specified (here, the value is 3). This will generate an exception.
To correct the problem, we only need to check if the caracter after the "[" is a "]". If this is not the case, skip the current iterate context and call it's parent "processProperty" method if there is still an unprocessed "[" in the property.
We also need a getParent() method in IterateContext that will return it's parent IterateContext.
I will send a new File containing my suggested patch.

The same problem applies to ConditionalTagHandler. Jeff, I'm sorry I didn't see the problem #3 you are talking about. Can you show me an exemple where this kind of bug happens? I may have already a part of the solution for the problem.
Maybe the problem can be solved by adding this code to ConditionalTagHandler doStartFragment() method.
              // Increase index if the first tag is another iterate.
              IterateContext itCtx = ctx.peekIterateContext();
              if(null != itCtx && itCtx.isAllowNext()){
                  itCtx.next();
                  itCtx.setAllowNext(false);
                  if(!itCtx.hasNext()) {
                      itCtx.setFinal(true);
                  }
              }


The DynamicSql class could also make a call to "iterateContext.processProperty();" to replace the body content replacing my code.

These changes will make the patch easier to maintain for future development.


For problem #2, applying these changes could result in correcting the bug... If this is not the case, I will try to find a patch for it and send it in this bug report.
> Nested iterate tags does not work > --------------------------------- > > Key: IBATIS-281 > URL: http://issues.apache.org/jira/browse/IBATIS-2... > Project: iBatis for Java > Type: Bug > Components: SQL Maps > Versions: 2.1.7 > Reporter: Christian Poitras > Assignee: Jeff Butler > Attachments: ConditionalTagHandler.java, DynamicSql.java, IterateTagHandler.java > > No nested iterate tags work. The second iterate tag is not supported and produces the following error. > java.lang.NumberFormatException: For input string: "" > at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) > at java.lang.Integer.parseInt(Integer.java:489) > at java.lang.Integer.parseInt(Integer.java:518) > at com.ibatis.common.beans.BaseProbe.getIndexedProperty(BaseProbe.java:51) > at com.ibatis.common.beans.ComplexBeanProbe.getProperty(ComplexBeanProbe.java:297) > at com.ibatis.common.beans.ComplexBeanProbe.getObject(ComplexBeanProbe.java:188) > at com.ibatis.common.beans.GenericProbe.getObject(GenericProbe.java:76) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.IterateTagHandler.doStartFragment(IterateTagHandler.java:34) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:157) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:160) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:99) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.process(DynamicSql.java:79) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.getParameterMap(DynamicSql.java:61) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:156) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForList(GeneralStatement.java:123) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:610) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:584) > at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:101) > at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:78) > at com.ibatis.dao.client.template.SqlMapDaoTemplate.queryForList(SqlMapDaoTemplate.java:203) > at ca.qc.ircm.lana.persistence.sqlmapdao.SpotSqlMapDao.getSpotsInter(SpotSqlMapDao.java:159) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at com.ibatis.dao.engine.impl.DaoProxy.invoke(DaoProxy.java:72) > at $Proxy14.getSpotsInter(Unknown Source) > at ca.qc.ircm.lana.service.InterpretationService.getSpotsInter(InterpretationService.java:82) > at TEST.testInterpretation.main(testInterpretation.java:111) > It seems the second iterate tag cannot have a property of this type. > <iterate property="list" > > <iterate property="list[].list"> > <iterate> > </iterate> > On the nested iterate, SQL Maps does not add the number in attribute property "list[].list" and tries to call a getter for parameterClass.getList[]() and this is not allowed and produces the error. > This could be prevented in the IterateTagHandler class (doStartFragment method) by adding code that replaces "[]" in the property attribute by values of IterateContext that are parents of the current tag (for multiple nested iterate). > Other code would need to be updated since using a property in the second list also causes SQL Map to crash even it IterateTagHandler is patched. > <iterate property="list" > > <iterate property="list[].list"> > #list[].list[].someProperty# > <iterate> > </iterate> > I produced a patch that can correct the problem. I will include it in a future message.
Jeff Butler (JIRA) 1147818518Tue, 16 May 2006 22:28:38 +0000 (UTC)
[ http://issues.apache.org/jira/browse/IBATIS-2... ] 

Jeff Butler commented on IBATIS-281:
------------------------------------

I just discovered that I can resolve the class #3 errors by rewriting the SqlMaps somewhat.  If I do something like this...

<iterate property="idList" removeFirstPrepend="true">
  <isNotEqual property="idList[]" compareValue="4" prepend="or">
    id = #idList[]#
  </isNotEqual>
</iterate>

...then all is well.  So maybe this is just a misunderstanding on my part?  Maybe we're closer to a fix than I thought.
> Nested iterate tags does not work > --------------------------------- > > Key: IBATIS-281 > URL: http://issues.apache.org/jira/browse/IBATIS-2... > Project: iBatis for Java > Type: Bug > Components: SQL Maps > Versions: 2.1.7 > Reporter: Christian Poitras > Assignee: Jeff Butler > Attachments: ConditionalTagHandler.java, DynamicSql.java, IterateContext.java, IterateTagHandler.java, test.zip > > No nested iterate tags work. The second iterate tag is not supported and produces the following error. > java.lang.NumberFormatException: For input string: "" > at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) > at java.lang.Integer.parseInt(Integer.java:489) > at java.lang.Integer.parseInt(Integer.java:518) > at com.ibatis.common.beans.BaseProbe.getIndexedProperty(BaseProbe.java:51) > at com.ibatis.common.beans.ComplexBeanProbe.getProperty(ComplexBeanProbe.java:297) > at com.ibatis.common.beans.ComplexBeanProbe.getObject(ComplexBeanProbe.java:188) > at com.ibatis.common.beans.GenericProbe.getObject(GenericProbe.java:76) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.IterateTagHandler.doStartFragment(IterateTagHandler.java:34) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:157) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:160) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:99) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.process(DynamicSql.java:79) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.getParameterMap(DynamicSql.java:61) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:156) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForList(GeneralStatement.java:123) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:610) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:584) > at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:101) > at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:78) > at com.ibatis.dao.client.template.SqlMapDaoTemplate.queryForList(SqlMapDaoTemplate.java:203) > at ca.qc.ircm.lana.persistence.sqlmapdao.SpotSqlMapDao.getSpotsInter(SpotSqlMapDao.java:159) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at com.ibatis.dao.engine.impl.DaoProxy.invoke(DaoProxy.java:72) > at $Proxy14.getSpotsInter(Unknown Source) > at ca.qc.ircm.lana.service.InterpretationService.getSpotsInter(InterpretationService.java:82) > at TEST.testInterpretation.main(testInterpretation.java:111) > It seems the second iterate tag cannot have a property of this type. > <iterate property="list" > > <iterate property="list[].list"> > <iterate> > </iterate> > On the nested iterate, SQL Maps does not add the number in attribute property "list[].list" and tries to call a getter for parameterClass.getList[]() and this is not allowed and produces the error. > This could be prevented in the IterateTagHandler class (doStartFragment method) by adding code that replaces "[]" in the property attribute by values of IterateContext that are parents of the current tag (for multiple nested iterate). > Other code would need to be updated since using a property in the second list also causes SQL Map to crash even it IterateTagHandler is patched. > <iterate property="list" > > <iterate property="list[].list"> > #list[].list[].someProperty# > <iterate> > </iterate> > I produced a patch that can correct the problem. I will include it in a future message.
Christian Poitras (JIRA) 1147962820Thu, 18 May 2006 14:33:40 +0000 (UTC)
[ http://issues.apache.org/jira/browse/IBATIS-2... ] 

Christian Poitras commented on IBATIS-281:
------------------------------------------

Great patch for the other problems, Jeff!
Everything seems to work fine here to.

I you want to rename (and rearrange, comment some code) the methods I created, go ahead. I am not totally used to the code in the framework, and I don't know your programming convetions.
> Nested iterate tags does not work > --------------------------------- > > Key: IBATIS-281 > URL: http://issues.apache.org/jira/browse/IBATIS-2... > Project: iBatis for Java > Type: Bug > Components: SQL Maps > Versions: 2.1.7 > Reporter: Christian Poitras > Assignee: Jeff Butler > Attachments: ConditionalTagHandler.java, DynamicSql.java, IterateContext.java, IteratePatchTest1.zip, IteratePatchTest2.zip, IteratePatchTest3.zip, IterateTagHandler.java, test.zip, test2.zip, test3.zip > > No nested iterate tags work. The second iterate tag is not supported and produces the following error. > java.lang.NumberFormatException: For input string: "" > at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) > at java.lang.Integer.parseInt(Integer.java:489) > at java.lang.Integer.parseInt(Integer.java:518) > at com.ibatis.common.beans.BaseProbe.getIndexedProperty(BaseProbe.java:51) > at com.ibatis.common.beans.ComplexBeanProbe.getProperty(ComplexBeanProbe.java:297) > at com.ibatis.common.beans.ComplexBeanProbe.getObject(ComplexBeanProbe.java:188) > at com.ibatis.common.beans.GenericProbe.getObject(GenericProbe.java:76) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.IterateTagHandler.doStartFragment(IterateTagHandler.java:34) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:157) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:160) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:99) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.process(DynamicSql.java:79) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.getParameterMap(DynamicSql.java:61) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:156) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForList(GeneralStatement.java:123) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:610) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:584) > at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:101) > at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:78) > at com.ibatis.dao.client.template.SqlMapDaoTemplate.queryForList(SqlMapDaoTemplate.java:203) > at ca.qc.ircm.lana.persistence.sqlmapdao.SpotSqlMapDao.getSpotsInter(SpotSqlMapDao.java:159) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at com.ibatis.dao.engine.impl.DaoProxy.invoke(DaoProxy.java:72) > at $Proxy14.getSpotsInter(Unknown Source) > at ca.qc.ircm.lana.service.InterpretationService.getSpotsInter(InterpretationService.java:82) > at TEST.testInterpretation.main(testInterpretation.java:111) > It seems the second iterate tag cannot have a property of this type. > <iterate property="list" > > <iterate property="list[].list"> > <iterate> > </iterate> > On the nested iterate, SQL Maps does not add the number in attribute property "list[].list" and tries to call a getter for parameterClass.getList[]() and this is not allowed and produces the error. > This could be prevented in the IterateTagHandler class (doStartFragment method) by adding code that replaces "[]" in the property attribute by values of IterateContext that are parents of the current tag (for multiple nested iterate). > Other code would need to be updated since using a property in the second list also causes SQL Map to crash even it IterateTagHandler is patched. > <iterate property="list" > > <iterate property="list[].list"> > #list[].list[].someProperty# > <iterate> > </iterate> > I produced a patch that can correct the problem. I will include it in a future message.
Jeff Butler (JIRA) 1147975240Thu, 18 May 2006 18:00:40 +0000 (UTC)
[ http://issues.apache.org/jira/browse/IBATIS-2... ]
     
Jeff Butler closed IBATIS-281:
------------------------------

    Fix Version: 2.2.0
     Resolution: Fixed

Fixed in SVN.

In addition to the patches here, there were some additional changes to IterateContext and IterateTagHandler that account for prepends, opens, and closes correctly in a variety of situations.  I also added tests to the iBATIS build to prove the fixes.

Thanks again Christian - I enjoyed our collaboration.
> Nested iterate tags does not work > --------------------------------- > > Key: IBATIS-281 > URL: http://issues.apache.org/jira/browse/IBATIS-2... > Project: iBatis for Java > Type: Bug > Components: SQL Maps > Versions: 2.1.7 > Reporter: Christian Poitras > Assignee: Jeff Butler > Fix For: 2.2.0 > Attachments: ConditionalTagHandler.java, DynamicSql.java, IterateContext.java, IteratePatchTest1.zip, IteratePatchTest2.zip, IteratePatchTest3.zip, IterateTagHandler.java, test.zip, test2.zip, test3.zip > > No nested iterate tags work. The second iterate tag is not supported and produces the following error. > java.lang.NumberFormatException: For input string: "" > at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) > at java.lang.Integer.parseInt(Integer.java:489) > at java.lang.Integer.parseInt(Integer.java:518) > at com.ibatis.common.beans.BaseProbe.getIndexedProperty(BaseProbe.java:51) > at com.ibatis.common.beans.ComplexBeanProbe.getProperty(ComplexBeanProbe.java:297) > at com.ibatis.common.beans.ComplexBeanProbe.getObject(ComplexBeanProbe.java:188) > at com.ibatis.common.beans.GenericProbe.getObject(GenericProbe.java:76) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.IterateTagHandler.doStartFragment(IterateTagHandler.java:34) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:157) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:160) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:99) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.process(DynamicSql.java:79) > at com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.getParameterMap(DynamicSql.java:61) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:156) > at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForList(GeneralStatement.java:123) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:610) > at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:584) > at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:101) > at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:78) > at com.ibatis.dao.client.template.SqlMapDaoTemplate.queryForList(SqlMapDaoTemplate.java:203) > at ca.qc.ircm.lana.persistence.sqlmapdao.SpotSqlMapDao.getSpotsInter(SpotSqlMapDao.java:159) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at com.ibatis.dao.engine.impl.DaoProxy.invoke(DaoProxy.java:72) > at $Proxy14.getSpotsInter(Unknown Source) > at ca.qc.ircm.lana.service.InterpretationService.getSpotsInter(InterpretationService.java:82) > at TEST.testInterpretation.main(testInterpretation.java:111) > It seems the second iterate tag cannot have a property of this type. > <iterate property="list" > > <iterate property="list[].list"> > <iterate> > </iterate> > On the nested iterate, SQL Maps does not add the number in attribute property "list[].list" and tries to call a getter for parameterClass.getList[]() and this is not allowed and produces the error. > This could be prevented in the IterateTagHandler class (doStartFragment method) by adding code that replaces "[]" in the property attribute by values of IterateContext that are parents of the current tag (for multiple nested iterate). > Other code would need to be updated since using a property in the second list also causes SQL Map to crash even it IterateTagHandler is patched. > <iterate property="list" > > <iterate property="list[].list"> > #list[].list[].someProperty# > <iterate> > </iterate> > I produced a patch that can correct the problem. I will include it in a future message.
Home | About | Privacy