Search code examples
javajdbcmybatisspring-mybatis

mybatis jdbc select query is not working throws Invalid column index


I am having below issue in mybatis version 3.Please help me to find this.

Java Code:

@Select("SELECT A.PERSON_ID,A.PERSON_ADDRESS, C.CUSTOMER_NAME," + 
            "       B.CUSTOMER_DOB," + 
            "   FROM PERSON A, CUSTOMER B, CUSTOMER_DETAILS C" + 
            "  WHERE A.CUSTOMER_ID=C.CUSTOMER_ID" + 
            "  AND A.CUSTOMER_ID=B.CUSTOMER_ID (+)" + 
            "  AND C.PERSON_NAME='#{personName, jdbcType=VARCHAR,    mode=IN,  javaType=String}'" + 
            "  AND C.CUSTOMER_ID='#{customerID, jdbcType=VARCHAR,    mode=IN,  javaType=String}'")
    @Results(value = {
       @Result(property = "personId", column = "PERSON_ID"),
       @Result(property = "personAddress", column = "PERSON_ADDRESS"),
       @Result(property = "customerName", column = "CUSTOMER_NAME"),
       @Result(property = "customerDOB", column = "CUSTOMER_DOB")
    })
    List<PersonCustomerDetail> getPersonCustomerByID(@Param("personName") String personName,@Param("customerID") String customerID);

Exception trace:

nested exception is org.apache.ibatis.type.TypeException: 
Could not set parameters for mapping: ParameterMapping{property='personName', mode=IN, javaType=class java.lang.String, jdbcType=VARCHAR, 
numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. 
Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #1 with JdbcType VARCHAR . 
Try setting a different JdbcType for this parameter or a different configuration property. Cause: java.sql.SQLException: Invalid column index

Solution

  • The problem is with parameters passing to the query.

    When you use expression like #{parameterName} to specify a parameter mybatis transforms it to the jdbc parameter placeholder ? and then sets the parameter by index. For this query:

     select * from  a where col = #{param}
    

    the query generated by mybatis would be:

     select * from a where col = ?
    

    Because you quoted the parameter like this:

     select * from  a where col = '#{param}'
    

    the generated query becomes:

     select * from  a where col = '?'
    

    And this is treated by JDBC API as a query without any parameters so when mybatis tries to set parameters using JDBC PreparedStatement API the error is that parameter index is invalid.

    To fix the issue remove the quotes:

    @Select("SELECT A.PERSON_ID,A.PERSON_ADDRESS, C.CUSTOMER_NAME," + 
        "       B.CUSTOMER_DOB," + 
        "   FROM PERSON A, CUSTOMER B, CUSTOMER_DETAILS C" + 
        "  WHERE A.CUSTOMER_ID=C.CUSTOMER_ID" + 
        "  AND A.CUSTOMER_ID=B.CUSTOMER_ID (+)" + 
        "  AND C.PERSON_NAME=#{personName, jdbcType=VARCHAR, mode=IN, javaType=String}" + 
        "  AND C.CUSTOMER_ID=#{customerID, jdbcType=VARCHAR, mode=IN, javaType=String}")