java.sql.PreparedStatement.setArray():不支持的交叉转换

java.sql.PreparedStatement.setArray():不支持的交叉转换,java,sql,jdbc,db2,db2-luw,Java,Sql,Jdbc,Db2,Db2 Luw,当我使用jdbc运行下面的查询时,得到如下所示的异常。 这是一个简化的示例,preparedStatementSetter的其他部分以及setString和setInt等成功运行 public List<EmployeeMonitoringResultTo> searchEmployeesForEmployerInRange(final GetEmployeesForEmployerInRangeCriteria criteria) { final StringBuilder

当我使用jdbc运行下面的查询时,得到如下所示的异常。 这是一个简化的示例,preparedStatementSetter的其他部分以及setString和setInt等成功运行

public List<EmployeeMonitoringResultTo> searchEmployeesForEmployerInRange(final GetEmployeesForEmployerInRangeCriteria criteria) {
    final StringBuilder sql = 
    new StringBuilder(  "select * from CODES c ")
                .append("    where c.TYPE in ( ? )  "); // TYPE has DATA_TYPE 12, TYPE_NAME VARCHAR

    return jdbcTemplate.query(
        sql.toString(),
        new PreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps) throws SQLException {
                ps.setArray(1, searchTypes());
            }
        },
        new SpecificRowMapper<SpecType>()
        );      
}

private Array searchTypes() {
    final Collection<String> collection = fetchStrings();

    Array resultArray = null;;
    try {
        resultArray = jdbcTemplate.getDataSource().getConnection().createArrayOf("VARCHAR", collection.toArray());
    } catch (SQLException e) {
        log.error("Problem with created java.sql.Array", e);
        throw e;
    }

    return resultArray;
}
公共列表SearchEmployeesForemployerRange(最终GetEmployeesForemployerRangeCriteria){
最终StringBuilder sql=
新建StringBuilder(“从代码c中选择*)
.append(“其中c.TYPE in(?);//类型具有数据类型12,类型名称VARCHAR
返回jdbcTemplate.query(
sql.toString(),
新的PreparedStatementSetter(){
@凌驾
public void setValues(PreparedStatement ps)引发SQLException{
ps.setArray(1,searchTypes());
}
},
新的SpecificRowMapper()
);      
}
专用数组searchTypes(){
最终集合集合=fetchStrings();
数组resultArray=null;;
试一试{
resultArray=jdbcTemplate.getDataSource().getConnection().createArrayOf(“VARCHAR”,collection.toArray());
}捕获(SQLE异常){
log.error(“创建的java.sql.Array存在问题”,e);
投掷e;
}
返回结果数组;
}
原因:com.ibm.db2.jcc.am.SqlSyntaxErrorException: [jcc][10349][11717][4.13.80]不支持源的交叉转换 键入对象;。错误代码=-4461,SQLSTATE=42815 at com.ibm.db2.jcc.am.id.a(id.java:677)位于 com.ibm.db2.jcc.am.id.a(id.java:60)位于 com.ibm.db2.jcc.am.id.a(id.java:103)位于 com.ibm.db2.jcc.am.ic.a(ic.java:289)位于 com.ibm.db2.jcc.am.ic.a(ic.java:191)位于 com.ibm.db2.jcc.am.kc.a(kc.java:1943)位于 com.ibm.db2.jcc.am.go.a(go.java:2289)位于 com.ibm.db2.jcc.am.go.setArray(go.java:2254)位于 com.jolbox.bonecp.PreparedStatementHandle.setArray(PreparedStatementHandle.java:261) 在 net.sf.log4jdbc.PreparedStatementSpy.setArray(PreparedStatementSpy.java:349) 位于的sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) invoke(NativeMethodAccessorImpl.java:39) 在 reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 位于java.lang.reflect.Method.invoke(Method.java:597) org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122) ... 93多


toArray方法返回一个对象数组。您可以尝试使用字符串数组:

collection.toArray(new String[0]);
无论如何,您可能无法将SQL数组与IN运算符一起使用,因此您必须生成SQL,而不是使用准备好的语句。(或者至少生成正确数量的问号,然后在循环中设置参数,如注释中所建议的。)


您还缺少
where
关键字。

是的,您不能这样做。您需要计算出在
in
子句中需要多少
符号,并分别设置参数。你不能像这样在子句中将整个数组设置成一个
。事实上@DavidWallace,你是对的。你发布答案还是我发布?我诚实的感觉是,答案中有足够的信息,在这里复制这些信息是没有意义的。没错,巴卢斯的答案非常清楚。我使用了Strings.repeat(“?”,“,”,types.size());以生成查询。我要关上这个。答:在我的简化示例中,我确实忘记了“where”。我尝试使用您的解决方案,但不幸的是,我也遇到了以下错误:com.ibm.db2.jcc.am.SqlSyntaxErrorException:[jcc][1091][10417][4.13.80]无效数据转换:参数实例com.ibm.db2.jcc.am。o@5aaeaeb2对于请求的转换无效。ERRORCODE=-4461,SQLSTATE=42815