Reputation: 141
It might be a direct question but I'm trying many options which is not working. I've given the below details for your reference. Mybatis xml configuration:-
<select id="updateComps" statementType="CALLABLE" parameterType="java.util.List">
<![CDATA[ {call vivo.select_workout (#{list, mode=IN, jdbcType=ARRAY})}]]>
</select>
Postgres Function:-
CREATE OR REPLACE FUNCTION vivo.delete_completed_activity_logged_workout(INT[])
RETURNS integer
LANGUAGE plpgsql
AS $function$
declare
ids ALIAS FOR $1;
dist BIGINT[];
Mapper config:-
void deleteCompletedActivityRecords(List<Integer> users);
Error facing:-
aused by: org.apache.ibatis.type.TypeException: Error setting non null for parameter #1 with JdbcType ARRAY . Try setting a different JdbcType for this parameter or a different configuration property. Cause: java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.sql.Array at org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:55) at org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:87) ... 68 more Caused by: java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.sql.Array at org.apache.ibatis.type.ArrayTypeHandler.setNonNullParameter(ArrayTypeHandler.java:35) at org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:53) ... 69 more [WARNING] Could not send response error 500: javax.servlet.ServletException: javax.servlet.ServletException: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property='list', mode=IN, javaType=class java.lang.Object, jdbcType=ARRAY, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #1 with JdbcType ARRAY . Try setting a different JdbcType for this parameter or a different configuration property. Cause: java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.sql.Array
Upvotes: 0
Views: 2044
Reputation: 1616
You can use MyBatis' script engine to build a query like this to cast your list to INT[]:
call vivo.select_workout (ARRAY [1,2,3,4,5,6]::INT[])
For example:
<select id="updateComps" statementType="CALLABLE" parameterType="java.util.List">
{call vivo.select_workout (ARRAY <foreach item="userId" collection="users" open="[" separator="," close="]">#{userId}</foreach>::INT[]) }
</select>
Upvotes: 0
Reputation: 141
I created the below custom ArrayTypeHandler.
package com.lf.util;
import com.google.common.collect.Lists;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.JdbcType;
import java.sql.*;
import java.util.List;
@MappedJdbcTypes(JdbcType.ARRAY)
public class CustomArrayTypeHandler extends BaseTypeHandler<List<Long>> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<Long> parameter, JdbcType jdbcType) throws SQLException {
Array array = ps.getConnection().createArrayOf("integer", parameter.toArray());
ps.setArray(i, array);
}
@Override
public List<Long> getNullableResult(ResultSet rs, String columnName) throws SQLException {
return toList(rs.getArray(columnName));
}
@Override
public List<Long> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return toList(rs.getArray(columnIndex));
}
@Override
public List<Long> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return toList(cs.getArray(columnIndex));
}
private List<Long> toList(Array pgArray) throws SQLException {
if (pgArray == null) return Lists.newArrayList();
Long[] strings = (Long[]) pgArray.getArray();
return containsOnlyNulls(strings) ? Lists.<Long>newArrayList() : Lists.newArrayList(strings);
}
private boolean containsOnlyNulls(Long[] strings) {
for (Long s : strings) {
if (s != null) {
return false;
}
}
return true;
}
}
And in the xml file:
<select id="deleteRecords" statementType="CALLABLE" resultType="java.lang.Integer" parameterType="java.util.List">
<![CDATA[ {call vivo.delete_records (#{list, mode=IN, typeHandler=com.lf.util.CustomArrayTypeHandler})}]]>
</select>
Upvotes: 0