Search code examples
javapostgresqlibatis

How to send a List in select query of IBatis?


I am using Java 1.7, IBatis and postgreSQL

I have a StudentVO

import java.util.List;
    public class StudentVO {

        private Long studentId;
        private String studentName;
        private List<Long> studentFriendNums;

        //getters and setters
    }

My Function in postgreSQL is get_party_details(VARIADIC bigint[])

CREATE OR REPLACE FUNCTION get_party_details(VARIADIC bigint[])
  RETURNS TABLE(studentid bigint,studentName character varying, amtPaid numeric) AS
$BODY$
     DECLARE
        SQL VARCHAR;
BEGIN
    RETURN QUERY
        SELECT
             STU.student_id   as "Student ID"
            ,STU.student_name as "Student Name"
            ,STU.amt_paid     as "Amount Paid"

        FROM    STUDENT     STU

            WHERE STU.STUDENT_ID IN ( SELECT $1[I] FROM GENERATE_SUBSCRIPTS($1, 1) G(I));
END;

$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
  ROWS 1000;

My Function Returns the following Results:

select * from get_party_details(101,102,103,104);

StudentId  Student Name     Amt Paid
101          JOHN           428000.00
102          SMITH          275405.00
103          JACKSON        109250.00
104          LOVELESS       63200.00

My queries.xml

<select id="get_party_details" parameterType="StudentVO" 
        statementType="PREPARED" resultMap="partyMap">
            select * from get_party_details(#{studentFriendNums})
</select>

    <resultMap type="StudentVO" id="partyMap">
        <result property="studentId"            column="studentid" />
        <result property="studentName"          column="studentname" />
        <result property="amtPaid"              column="amtpaid" />
    </resultMap>

If i use the above Select Statement i am getting the below Exception:

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'studentFriendNums'.  It was either not specified and/or could not be found for the javaType / jdbcType combination specified.
### Cause: java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'studentFriendNums'.  It was either not specified and/or could not be found for the javaType / jdbcType combination specified.

Any help/suggestions ?

Edit 1: I Tried a foreach loop as well which didn't get me out of the issue.

<select id="get_party_details" parameterType="StudentVO" statementType="PREPARED" resultMap="partyMap">
        select * from get_party_details(
        <foreach item="friends" index="index" collection="studentFriendNums"
            open="(" separator="," close=")">
            #{friends}
        </foreach>
        )
    </select>

Exception with <foreach/>:

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.postgresql.util.PSQLException: ERROR: function get_party_details(record) does not exist
  Hint: No function matches the given name and argument types. You might need to add explicit type casts.
  Position: 15
### The error may exist in com/myblog/queries.xml
### The error may involve com.myblog.StudentDAO.get_party_details-Inline
### The error occurred while setting parameters
### SQL: select * from epc.get_party_details(    (      ?    ,     ?    ,     ?    ,     ?    )    )
### Cause: org.postgresql.util.PSQLException: ERROR: function get_party_details(record) does not exist
  Hint: No function matches the given name and argument types. You might need to add explicit type casts.
  Position: 15

Edit 2: My Ibatis version is 3.2.3

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.myblog.StudentDTO">

    <select id="get_party_details" parameterType="StudentVO" 
      statementType="PREPARED" resultMap="partyMap">
        select * from get_party_details
     <iterate property="studentFriendNums" conjunction="," open = "(" close = ")">
            #studentFriendNums[]#
     </iterate>
</select>

    <resultMap type="StudentVO" id="partyMap">
        <result property="studentId"            column="studentid" />
        <result property="studentName"          column="studentname" />
        <result property="amtPaid"              column="amtpaid" />
    </resultMap>

</mapper>

Solution

  • You can use a foreach :

       <select id="get_party_details" parameterType="StudentVO" 
                statementType="PREPARED" resultMap="partyMap">
                    select * from get_party_details
                    <foreach item="item" index="index" collection="studentFriendNums"
                        open="(" separator="," close=")">
                    #{item}
                   </foreach>
        </select>
    

    Just saw your first edit, you don't need to open and close bracket before and after the foreach. Parameter open and close do it for you.