如何调用传递 List<String> 作为参数的 DB2 存储过程?
How to call a DB2 stored procedure passing a List<String> as param?
Java版本:Java1.8
JDBC:db2jcc4-11.1.1.1
Ant1.7
Websphere8.5
我正在升级服务以允许将一组货币代码(AA、BB、CC、DD)传递到存储过程中。 NSP 工作已经完成并得到验证。下面是我的代码。
映射器
<!-- Call XXXXXXX- InputArray -->
<select id="addOrRemoveDataList" statementType="CALLABLE"
parameterType="globalTradeAwayParams">
{CALL ${dbPackageName}.XXXXXXX
(#{param.ownerId, mode=IN, jdbcType=INTEGER},
#{param.actionInd, mode=IN, jdbcType=CHAR},
#{param.addOrRemoveElementsCount, mode=IN, jdbcType=INTEGER},
#{param.addOrRemoveList, jdbcType=ARRAY, mode=IN, jdbcTypeName=VARCHAR, typeHandler=com.pseuplex.core.db.handlers.StringHandler})}
</select>
StringHandler
public class StringHandler implements TypeHandler<List<String>> {
// Adding logger to StringHandler
private static Logger log = Logger.getLogger(StringHandler.class);
@Override
public void setParameter(PreparedStatement arg0, int arg1, List<String> arg2, JdbcType arg3) throws SQLException {
// TODO Auto-generated method stub
log.info("Prepared statement: " + arg0.toString());
log.info("Arg1: " + arg1);
log.info("Object: " + arg2);
log.info("JDBC Type: " + arg3);
// TODO Auto-generated method stub
Array string = null;
int index = 0;
String[] stringArray;
if (arg2 == null)
stringArray = new String[0];
else {
stringArray = new String[arg2.size()];
for (String i : arg2) {
stringArray[index] = i;
index++;
}
}
Connection con = arg0.getConnection();
// ERROR THROWN HERE
string = con.createArrayOf("VARCHAR", stringArray);
arg0.setArray(arg1, string);
}
@Override
public List<String> getResult(ResultSet arg0, String arg1)
throws SQLException {
// TODO Auto-generated method stub
return new ArrayList<String>();
}
@Override
public List<String> getResult(ResultSet arg0, int arg1) throws SQLException {
// TODO Auto-generated method stub
return new ArrayList<String>();
}
@Override
public List<String> getResult(CallableStatement arg0, int arg1)
throws SQLException {
// TODO Auto-generated method stub
return new ArrayList<String>();
}
}
在运行时,我在将更改提交到我的数据库时遇到此错误:
致命 com.pseuplex.j2ee.ExceptionFilter - java/sql/Connection.createArrayOf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/sql/Array ;
java.lang.AbstractMethodError: java/sql/Connection.createArrayOf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/sql/Array;
我查看了与此类似的堆栈溢出问题页面,但 none 的解决方案使我找到了解决方案。任何帮助将不胜感激。
关于 AbstractMethod 错误,当您调用比实现实际实现的 JDBC 规范级别更高的接口方法时,通常会发生这种情况。 java.sql.Connection.createArrayOf 方法是在 JDBC 4.0 中添加的。您是否正在使用较旧的规范级别 JDBC 驱动程序 JAR,它实现了较旧的版本,例如缺少 createArrayOf 方法的 JDBC 3.0?根据您报告的错误,这似乎是一个很好的可能性。如果是这样,只需升级到 JDBC 驱动程序的更新规格级别版本。
只是为了将来参考而跟进,我找到了解决 AbstractMethodError 的方法。我使用的是旧版本的 dbcp,最后不得不升级到 commons-dbcp2 和 commons-pool2。
升级后,我只是将数据源更改为目标 dbcp2,一切正常。
Java版本:Java1.8
JDBC:db2jcc4-11.1.1.1
Ant1.7
Websphere8.5
我正在升级服务以允许将一组货币代码(AA、BB、CC、DD)传递到存储过程中。 NSP 工作已经完成并得到验证。下面是我的代码。
映射器
<!-- Call XXXXXXX- InputArray -->
<select id="addOrRemoveDataList" statementType="CALLABLE"
parameterType="globalTradeAwayParams">
{CALL ${dbPackageName}.XXXXXXX
(#{param.ownerId, mode=IN, jdbcType=INTEGER},
#{param.actionInd, mode=IN, jdbcType=CHAR},
#{param.addOrRemoveElementsCount, mode=IN, jdbcType=INTEGER},
#{param.addOrRemoveList, jdbcType=ARRAY, mode=IN, jdbcTypeName=VARCHAR, typeHandler=com.pseuplex.core.db.handlers.StringHandler})}
</select>
StringHandler
public class StringHandler implements TypeHandler<List<String>> {
// Adding logger to StringHandler
private static Logger log = Logger.getLogger(StringHandler.class);
@Override
public void setParameter(PreparedStatement arg0, int arg1, List<String> arg2, JdbcType arg3) throws SQLException {
// TODO Auto-generated method stub
log.info("Prepared statement: " + arg0.toString());
log.info("Arg1: " + arg1);
log.info("Object: " + arg2);
log.info("JDBC Type: " + arg3);
// TODO Auto-generated method stub
Array string = null;
int index = 0;
String[] stringArray;
if (arg2 == null)
stringArray = new String[0];
else {
stringArray = new String[arg2.size()];
for (String i : arg2) {
stringArray[index] = i;
index++;
}
}
Connection con = arg0.getConnection();
// ERROR THROWN HERE
string = con.createArrayOf("VARCHAR", stringArray);
arg0.setArray(arg1, string);
}
@Override
public List<String> getResult(ResultSet arg0, String arg1)
throws SQLException {
// TODO Auto-generated method stub
return new ArrayList<String>();
}
@Override
public List<String> getResult(ResultSet arg0, int arg1) throws SQLException {
// TODO Auto-generated method stub
return new ArrayList<String>();
}
@Override
public List<String> getResult(CallableStatement arg0, int arg1)
throws SQLException {
// TODO Auto-generated method stub
return new ArrayList<String>();
}
}
在运行时,我在将更改提交到我的数据库时遇到此错误:
致命 com.pseuplex.j2ee.ExceptionFilter - java/sql/Connection.createArrayOf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/sql/Array ; java.lang.AbstractMethodError: java/sql/Connection.createArrayOf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/sql/Array;
我查看了与此类似的堆栈溢出问题页面,但 none 的解决方案使我找到了解决方案。任何帮助将不胜感激。
关于 AbstractMethod 错误,当您调用比实现实际实现的 JDBC 规范级别更高的接口方法时,通常会发生这种情况。 java.sql.Connection.createArrayOf 方法是在 JDBC 4.0 中添加的。您是否正在使用较旧的规范级别 JDBC 驱动程序 JAR,它实现了较旧的版本,例如缺少 createArrayOf 方法的 JDBC 3.0?根据您报告的错误,这似乎是一个很好的可能性。如果是这样,只需升级到 JDBC 驱动程序的更新规格级别版本。
只是为了将来参考而跟进,我找到了解决 AbstractMethodError 的方法。我使用的是旧版本的 dbcp,最后不得不升级到 commons-dbcp2 和 commons-pool2。
升级后,我只是将数据源更改为目标 dbcp2,一切正常。