Search code examples
spring-mvcibatisdynamic-sql

com.ibatis.common.jdbc.exception.NestedSQLException:


I am gettng this exception for this code

 List<String> addlCarrierClause=new ArrayList<String>();

<select id="GET_SEARCH_RESULTS" parameterClass="Map" resultClass="HashMap">

<isNotEmpty  prepend=" AND " property="addlClauseGtwyTemp">
    l.imp_gtwy_i in
        <iterate property="addlClauseGtwyTemp" open="(" close=")" conjunction=",">
            #addlClauseGtwyTemp[]#
        </iterate>
</isNotEmpty>

com.ibatis.common.jdbc.exception.NestedSQLException:

The error occurred while preparing the mapped statement for execution.  
--- Check the GET_SEARCH_RESULTS.  
--- Check the parameter map.  
--- Cause: com.ibatis.sqlmap.client.SqlMapException: ParameterObject or property was not a Collection, Array or Iterator.
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:45)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)

Am I using the iterate tag correctly?
What else do i need to check to implement this


Solution

  • You use iBatis <iterate> tag only when you want to cycle through a list of items. Your iterate tag usage is correct and your property addlClauseGtwyTemp exists otherwise you'll be getting a NullPointerException which you aren't getting. So your problem simply is that your addlClauseGtwyTemp isn't a list or an iterable collection (implementing an iterable interface) but a flat value.

    I was able to simulate your issue locally and i got the same stack trace in my logs

    2013-09-02 17:04:59,724 ERROR UNEXPECTED_EXCEPTION: An unexpected error occurred processing wlm.search
    com.xyz.event.InvalidEventStateException: wlm.searchCO:
    --- The error occurred in workListManagementSearchService.xml.
    --- The error occurred while preparing the mapped statement for execution.
    --- Check the getWLMSearchCustomers.
    --- Check the parameter map.
    --- Cause: com.ibatis.sqlmap.client.SqlMapException: ParameterObject or property was not a Collection, Array or Iterator.
            at com.xyz.event.Query.execute(Query.java:67)
            at com.xyz.event.AbstractParentExecutable.executeChildren(AbstractParentExecutable.java:35)
            at com.xyz.event.Event.execute(Event.java:32)
            at com.xyz.event.impl.d$a.processEvent(EventContextFactory.java:56)
    

    SOLUTION

    Ensure that your property addlClauseGtwyTemp is a list or a collection and not a flat value.

    LIST

    addlClauseGtwyTemp = [Asia,America,Austalia,Africa,SouthAmerica,Europe] 
    

    NON LIST

    addlClauseGtwyTemp = Asia
    

    EXTRA TIPS

    In your case you are guarding and checking this property addlClauseGtwyTemp is not null and not empty ("" or size() < 1) using <isNotEmpty> tag.

    Well, that's fine and i'll also commend that using <isNotEmpty> is more efficient than using <isNotNull> since <isNotNull> only checks if the property is not null but does not check if the property addlClauseGtwyTemp is not empty that is, the size of the property addlClauseGtwyTemp is less than 1 size() < 1. If it is null or if the size is less than 1 then the code nested in that tag will not run. But what happens if that property fails to met your <isNotEmpty> condition? Using your code that you have pasted in your question the query will throw an error. This means that you have to have a preceding code that does the reverse of this to handle situations where the condition fails to be satisfied.

    <select id="GET_SEARCH_RESULTS" parameterClass="Map" resultClass="HashMap">
    
        <isNotEmpty  prepend=" AND " property="addlClauseGtwyTemp">
            l.imp_gtwy_i in
            <iterate property="addlClauseGtwyTemp" open="(" close=")" conjunction=",">
            #addlClauseGtwyTemp[]#
            </iterate>
        </isNotEmpty>
    
        <isEmpty  prepend=" AND " property="addlClauseGtwyTemp">
           1=2
        </isEmpty>
    
        <isNull property="addlClauseGtwyTemp">
              select 1 from dual (Oracle syntax)
              select 1 (Postgres/MySQL)
        </isNull>
    
    </select>
    

    I added a fragment to check the reverse of isNotEmpty using <isEmpty> tag and i also checked if addlClauseGtwyTemp is null using <isNull>. If it is null then the query does nothing rather than throw an error.