namedParameterJdbcTemplate.batchUpdate(query..) 在查询中使用 in-clause 时出错
Getting error while namedParameterJdbcTemplate.batchUpdate(query..), when using in-clause in query
我正在尝试使用 org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate 批量更新 table。
namedParameterJdbcTemplate.batchUpdate(查询...)方法;
我的查询包含 in-clause,因此我得到 SQL 这样的错误:
nested exception is com.ibm.db2.jcc.am.SqlSyntaxErrorException: [jcc][1091][10824][4.14.113] Invalid data conversion: Parameter instance [1271, 1272] is invalid for the requested conversion. ERRORCODE=-4461, SQLSTATE=42815.
下面是我要批量更新的数据。它是 contractId(String) 的 Map 作为 key 和 value 作为 taskids List(Integer)
数据:
{10008=[1271, 1272], 10007=[1269, 1270], 10009=[1273, 1274], 10011=[1277, 1278], 10010=[1275, 1276], 10012=[1279], 10006=[1267, 1268]}
where key is the CONTRACT_ID (String) and value is list of TASK_ID ( Integer)
e.g. CONTRACT_ID are 10008, 10007, 10009 etc.
and respective TASK_ID are [1271, 1272], [1269, 1270], [1273, 1274] etc.
我尝试在循环内调用 namedParameterJdbcTemplate.update,它工作正常,我可以使用单个更新
更新相同的查询
单次更新
@Override
public int assignUserTask(String customerId, String userId, Map<String, List<Integer>> resultMap)
throws ApplicationException {
int totalCount = 0;
String ts = DateUtils.getCurrentDatetimeStamp();
String todaysDate = DateUtils.getTodaysDate();
String query = CommonUtils.buildQuery("UPDATE EM_WF_USER_QUEUE SET", "CURRENT_USER_ID = :currentUserId,",
"INITIAL_USER_ID = :initialUserId,", "USER_REASSIGN_TYPE_CD = 'GW',",
"USER_REASSIGN_TIME = :userReassignTime,", "LAST_CENTRAL_QUEUE_DATE = :lastCentralQueueData,",
"REASSIGN_CENTRAL_DATE = :reassignCentralDate,", "ORG_GW_CRT_TIME = :orgGwCreateTime,",
"LAST_UPDT_USER = :lastUpdtUser ,", "LAST_UPDT_TIME = :lastUpdtTime",
"WHERE CONTRACT_ID = :contractId AND TASK_ID IN (:taskIds)",
"AND CUSTOMER_ID = :customerId AND CURRENT_USER_ID = 'UNASSIGNED'",
"AND OVERIDE_IND = 'N' AND QUEUE_STATUS != 'CLOSED'");
try {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("currentUserId", userId);
params.addValue("initialUserId", userId);
params.addValue("userReassignTime", ts);
params.addValue("lastCentralQueueData", todaysDate);
params.addValue("reassignCentralDate", todaysDate);
params.addValue("orgGwCreateTime", ts);
params.addValue("lastUpdtUser", userId);
params.addValue("lastUpdtTime", ts);
params.addValue("customerId", customerId);
for (Entry<String, List<Integer>> entry : resultMap.entrySet()) {
params.addValue("contractId", entry.getKey());
params.addValue("taskIds", entry.getValue());
totalCount += namedParameterJdbcTemplate.update(query, params);
}
return totalCount;
} catch (DataAccessException exp) {
throw new CustomException(exp, "Exception occured!");
}
}
批量更新
@Override
public int assignUserTask(String customerId, String userId, Map> resultMap)
抛出 CustomException {
String ts = DateUtils.getCurrentDatetimeStamp();
String todaysDate = DateUtils.getTodaysDate();
String query = CommonUtils.buildQuery("UPDATE EM_WF_USER_TASK SET", "CURRENT_USER_ID = :currentUserId,",
"INITIAL_USER_ID = :initialUserId,", "USER_REASSIGN_TIME = :userReassignTime,",
"LAST_CENTRAL_QUEUE_DATE = :lastCentralQueueData,", "REASSIGN_CENTRAL_DATE = :reassignCentralDate,",
"ORG_GW_CRT_TIME = :orgGwCreateTime,", "LAST_UPDT_USER = :lastUpdtUser ,",
"LAST_UPDT_TIME = :lastUpdtTime", "WHERE CONTRACT_ID = :contractId AND TASK_ID IN (:taskIds)",
"AND CUSTOMER_ID = :customerId AND CURRENT_USER_ID = 'UNASSIGNED'",
"AND ACTIVE_IND = 'Y' AND TASK_STATUS != 'CLOSED'");
try {
List<MapSqlParameterSource> batchArgs = new ArrayList<>();
for (Entry<String, List<Integer>> entry : resultMap.entrySet()) {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("currentUserId", userId);
params.addValue("initialUserId", userId);
params.addValue("userReassignTime", ts);
params.addValue("lastCentralQueueData", todaysDate);
params.addValue("reassignCentralDate", todaysDate);
params.addValue("orgGwCreateTime", ts);
params.addValue("lastUpdtUser", userId);
params.addValue("lastUpdtTime", ts);
params.addValue("contractId", entry.getKey());
params.addValue("taskIds", entry.getValue());
params.addValue("customerId", customerId);
batchArgs.add(params);
}
int[] retVal = namedParameterJdbcTemplate.batchUpdate(query,
batchArgs.toArray(new MapSqlParameterSource[resultMap.size()]));
return retVal.length;
} catch (DataAccessException exp) {
throw new CustomException(exp, "Exception occured!");
}
}
我希望在使用 namedParameterJdbcTemplate.batchUpdate(query..)
时批量查询 运行
但它给出了类型转换错误。
Caused by: org.springframework.jdbc.BadSqlGrammarException:
PreparedStatementCallback; bad SQL grammar [UPDATE EM_WF_USER_TASK SET
CURRENT_USER_ID = ?, INITIAL_USER_ID = ?, USER_REASSIGN_TYPE_CD =
'GW', USER_REASSIGN_TIME = ?, LAST_CENTRAL_QUEUE_DATE = ?,
REASSIGN_CENTRAL_DATE = ?, ORG_GW_CRT_TIME = ?, LAST_UPDT_USER = ? ,
LAST_UPDT_TIME = ? WHERE CONTRACT_ID = ? AND TASK_ID IN (?, ?) AND
CUSTOMER_ID = ? AND CURRENT_USER_ID = 'UNASSIGNED' AND ACTIVE_IND =
'Y' AND TASK_STATUS != 'CLOSED' ]; nested exception is
com.ibm.db2.jcc.am.SqlSyntaxErrorException:
[jcc][1091][10824][4.14.113] Invalid data conversion: Parameter
instance [1271, 1272] is invalid for the requested conversion.
ERRORCODE=-4461, SQLSTATE=42815
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:93)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1402)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:620)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:634)
at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:924)
at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils.executeBatchUpdateWithNamedParameters(NamedParameterBatchUpdateUtils.java:43)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.batchUpdate(NamedParameterJdbcTemplate.java:357)
at com.medicare.mss.daoImpl.ContractDAO.assignUserTask(ContractDAO.java:274)
... 164 more
Caused by: com.ibm.db2.jcc.am.SqlSyntaxErrorException: [jcc][1091][10824][4.14.113] Invalid data conversion: Parameter
instance [1271, 1272] is invalid for the requested conversion.
ERRORCODE=-4461, SQLSTATE=42815
at com.ibm.db2.jcc.am.ed.a(ed.java:677)
at com.ibm.db2.jcc.am.ed.a(ed.java:60)
at com.ibm.db2.jcc.am.ed.a(ed.java:103)
at com.ibm.db2.jcc.am.po.c(po.java:2630)
at com.ibm.db2.jcc.am.po.setObject(po.java:2409)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.setObject(HikariProxyPreparedStatement.java)
at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:411)
at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:232)
at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:163)
at org.springframework.jdbc.core.BatchUpdateUtils.setStatementParameters(BatchUpdateUtils.java:70)
at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils.access[=16=]0(NamedParameterBatchUpdateUtils.java:33)
at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils.setValues(NamedParameterBatchUpdateUtils.java:50)
at org.springframework.jdbc.core.JdbcTemplate.lambda$batchUpdate(JdbcTemplate.java:932)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:605)
... 169 more
com.medicare.mss.exception.ApplicationException: Error occured while assignUserTask!
at com.medicare.mss.daoImpl.ContractDAO.assignUserTask(ContractDAO.java:279)
at com.medicare.mss.daoImpl.ContractDAO$$FastClassBySpringCGLIB$e66146.invoke()
...
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
我发现问题出在 batchUpdate 查询中的 IN 子句上。请检查以下 link。希望这可以帮助:
https://github.com/spring-projects/spring-framework/issues/21935
我正在尝试使用 org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate 批量更新 table。 namedParameterJdbcTemplate.batchUpdate(查询...)方法; 我的查询包含 in-clause,因此我得到 SQL 这样的错误:
nested exception is com.ibm.db2.jcc.am.SqlSyntaxErrorException: [jcc][1091][10824][4.14.113] Invalid data conversion: Parameter instance [1271, 1272] is invalid for the requested conversion. ERRORCODE=-4461, SQLSTATE=42815.
下面是我要批量更新的数据。它是 contractId(String) 的 Map 作为 key 和 value 作为 taskids List(Integer) 数据:
{10008=[1271, 1272], 10007=[1269, 1270], 10009=[1273, 1274], 10011=[1277, 1278], 10010=[1275, 1276], 10012=[1279], 10006=[1267, 1268]}
where key is the CONTRACT_ID (String) and value is list of TASK_ID ( Integer)
e.g. CONTRACT_ID are 10008, 10007, 10009 etc.
and respective TASK_ID are [1271, 1272], [1269, 1270], [1273, 1274] etc.
我尝试在循环内调用 namedParameterJdbcTemplate.update,它工作正常,我可以使用单个更新
更新相同的查询单次更新
@Override
public int assignUserTask(String customerId, String userId, Map<String, List<Integer>> resultMap)
throws ApplicationException {
int totalCount = 0;
String ts = DateUtils.getCurrentDatetimeStamp();
String todaysDate = DateUtils.getTodaysDate();
String query = CommonUtils.buildQuery("UPDATE EM_WF_USER_QUEUE SET", "CURRENT_USER_ID = :currentUserId,",
"INITIAL_USER_ID = :initialUserId,", "USER_REASSIGN_TYPE_CD = 'GW',",
"USER_REASSIGN_TIME = :userReassignTime,", "LAST_CENTRAL_QUEUE_DATE = :lastCentralQueueData,",
"REASSIGN_CENTRAL_DATE = :reassignCentralDate,", "ORG_GW_CRT_TIME = :orgGwCreateTime,",
"LAST_UPDT_USER = :lastUpdtUser ,", "LAST_UPDT_TIME = :lastUpdtTime",
"WHERE CONTRACT_ID = :contractId AND TASK_ID IN (:taskIds)",
"AND CUSTOMER_ID = :customerId AND CURRENT_USER_ID = 'UNASSIGNED'",
"AND OVERIDE_IND = 'N' AND QUEUE_STATUS != 'CLOSED'");
try {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("currentUserId", userId);
params.addValue("initialUserId", userId);
params.addValue("userReassignTime", ts);
params.addValue("lastCentralQueueData", todaysDate);
params.addValue("reassignCentralDate", todaysDate);
params.addValue("orgGwCreateTime", ts);
params.addValue("lastUpdtUser", userId);
params.addValue("lastUpdtTime", ts);
params.addValue("customerId", customerId);
for (Entry<String, List<Integer>> entry : resultMap.entrySet()) {
params.addValue("contractId", entry.getKey());
params.addValue("taskIds", entry.getValue());
totalCount += namedParameterJdbcTemplate.update(query, params);
}
return totalCount;
} catch (DataAccessException exp) {
throw new CustomException(exp, "Exception occured!");
}
}
批量更新
@Override public int assignUserTask(String customerId, String userId, Map> resultMap) 抛出 CustomException {
String ts = DateUtils.getCurrentDatetimeStamp();
String todaysDate = DateUtils.getTodaysDate();
String query = CommonUtils.buildQuery("UPDATE EM_WF_USER_TASK SET", "CURRENT_USER_ID = :currentUserId,",
"INITIAL_USER_ID = :initialUserId,", "USER_REASSIGN_TIME = :userReassignTime,",
"LAST_CENTRAL_QUEUE_DATE = :lastCentralQueueData,", "REASSIGN_CENTRAL_DATE = :reassignCentralDate,",
"ORG_GW_CRT_TIME = :orgGwCreateTime,", "LAST_UPDT_USER = :lastUpdtUser ,",
"LAST_UPDT_TIME = :lastUpdtTime", "WHERE CONTRACT_ID = :contractId AND TASK_ID IN (:taskIds)",
"AND CUSTOMER_ID = :customerId AND CURRENT_USER_ID = 'UNASSIGNED'",
"AND ACTIVE_IND = 'Y' AND TASK_STATUS != 'CLOSED'");
try {
List<MapSqlParameterSource> batchArgs = new ArrayList<>();
for (Entry<String, List<Integer>> entry : resultMap.entrySet()) {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("currentUserId", userId);
params.addValue("initialUserId", userId);
params.addValue("userReassignTime", ts);
params.addValue("lastCentralQueueData", todaysDate);
params.addValue("reassignCentralDate", todaysDate);
params.addValue("orgGwCreateTime", ts);
params.addValue("lastUpdtUser", userId);
params.addValue("lastUpdtTime", ts);
params.addValue("contractId", entry.getKey());
params.addValue("taskIds", entry.getValue());
params.addValue("customerId", customerId);
batchArgs.add(params);
}
int[] retVal = namedParameterJdbcTemplate.batchUpdate(query,
batchArgs.toArray(new MapSqlParameterSource[resultMap.size()]));
return retVal.length;
} catch (DataAccessException exp) {
throw new CustomException(exp, "Exception occured!");
}
}
我希望在使用 namedParameterJdbcTemplate.batchUpdate(query..)
时批量查询 运行
但它给出了类型转换错误。
Caused by: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [UPDATE EM_WF_USER_TASK SET CURRENT_USER_ID = ?, INITIAL_USER_ID = ?, USER_REASSIGN_TYPE_CD = 'GW', USER_REASSIGN_TIME = ?, LAST_CENTRAL_QUEUE_DATE = ?, REASSIGN_CENTRAL_DATE = ?, ORG_GW_CRT_TIME = ?, LAST_UPDT_USER = ? , LAST_UPDT_TIME = ? WHERE CONTRACT_ID = ? AND TASK_ID IN (?, ?) AND CUSTOMER_ID = ? AND CURRENT_USER_ID = 'UNASSIGNED' AND ACTIVE_IND = 'Y' AND TASK_STATUS != 'CLOSED' ]; nested exception is com.ibm.db2.jcc.am.SqlSyntaxErrorException: [jcc][1091][10824][4.14.113] Invalid data conversion: Parameter instance [1271, 1272] is invalid for the requested conversion. ERRORCODE=-4461, SQLSTATE=42815 at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:93) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1402) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:620) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:634) at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:924) at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils.executeBatchUpdateWithNamedParameters(NamedParameterBatchUpdateUtils.java:43) at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.batchUpdate(NamedParameterJdbcTemplate.java:357) at com.medicare.mss.daoImpl.ContractDAO.assignUserTask(ContractDAO.java:274) ... 164 more Caused by: com.ibm.db2.jcc.am.SqlSyntaxErrorException: [jcc][1091][10824][4.14.113] Invalid data conversion: Parameter instance [1271, 1272] is invalid for the requested conversion. ERRORCODE=-4461, SQLSTATE=42815 at com.ibm.db2.jcc.am.ed.a(ed.java:677) at com.ibm.db2.jcc.am.ed.a(ed.java:60) at com.ibm.db2.jcc.am.ed.a(ed.java:103) at com.ibm.db2.jcc.am.po.c(po.java:2630) at com.ibm.db2.jcc.am.po.setObject(po.java:2409) at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.setObject(HikariProxyPreparedStatement.java) at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:411) at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:232) at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:163) at org.springframework.jdbc.core.BatchUpdateUtils.setStatementParameters(BatchUpdateUtils.java:70) at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils.access[=16=]0(NamedParameterBatchUpdateUtils.java:33) at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils.setValues(NamedParameterBatchUpdateUtils.java:50) at org.springframework.jdbc.core.JdbcTemplate.lambda$batchUpdate(JdbcTemplate.java:932) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:605) ... 169 more com.medicare.mss.exception.ApplicationException: Error occured while assignUserTask! at com.medicare.mss.daoImpl.ContractDAO.assignUserTask(ContractDAO.java:279) at com.medicare.mss.daoImpl.ContractDAO$$FastClassBySpringCGLIB$e66146.invoke() ... at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745)
我发现问题出在 batchUpdate 查询中的 IN 子句上。请检查以下 link。希望这可以帮助: https://github.com/spring-projects/spring-framework/issues/21935