New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Include all SQL statements in batch fail exception [SPR-10677] #15305
Comments
Phil Webb commented What database server are you using? More specifically does it support batched updates? It appears that the SQL in the exception should be provided via the A repro project would also be very useful to help us replicate the problem. |
Lefebvre commented Please find a tests projets. |
Lefebvre commented Do you reprocuce the problem with my sample ? Sorry for my enlish :-) |
Phil Webb commented Reproduced the problem, thanks for the test project. The problem isn't that SQL in the exception contains the first element, rather that it contains the last. The reason for this is that your database supports batched updates so all the SQL is submitted as a single request. By the time the exception has been raised all the statements have been looped over and so the last one ends up in the message. This is obviously a bit misleading but I don't think we have a safe way to tell precisely which SQL statement failed. Probably the best that we can do is ensure that the exception contains all the SQL statements concatenated together. If you know that you will always be talking to HSQLDB it is possible to access the actual SQL that failed in the following (non portable) way: if(dataAccessException.getCause() instanceof JdbcSQLException) {
sql = ((JdbcSQLException) dataAccessException.getCause()).getSQL();
} |
Lefebvre commented Yes you can know failed statements doing that : List<String> sqlsToExecuteInBatch=new ArrayList<>();
try(Connection conn = DriverManager.getConnection("jdbc:h2:mem:test");Statement statement=conn.createStatement()){
sqlsToExecuteInBatch.add(String.format("BAD SQL FIRST"));
sqlsToExecuteInBatch.add("CREATE TABLE TEST (id INTEGER)");
for(int k=0;k<100;k++) {
sqlsToExecuteInBatch.add(String.format("INSERT INTO TEST VALUES(%s)", k));
}
sqlsToExecuteInBatch.add(sqlsToExecuteInBatch.size()/2,String.format("BAD SQL MIDDLE"));
sqlsToExecuteInBatch.add(sqlsToExecuteInBatch.size()/2,String.format("BAD SQL END"));
for(String sql:sqlsToExecuteInBatch) {
statement.addBatch(sql);
}
statement.executeBatch();
} catch(BatchUpdateException batchUpdateException) {
int[] updateCounts=batchUpdateException.getUpdateCounts();
List<String> failedStatements=new ArrayList<>();
for(int k=0;k<updateCounts.length;k++) {
if(updateCounts[k] == Statement.EXECUTE_FAILED) {
failedStatements.add(sqlsToExecuteInBatch.get(k));
}
}
for(String failedStatement:failedStatements) {
System.err.println(String.format("sqlStatementFailed [%s].",failedStatement));
}
} Display :
|
Phil Webb commented Thanks, I was not aware of that. |
Lefebvre commented :-) |
Lefebvre commented For other databases like oracle, the updateCounts stop after the first statement breaks |
Lefebvre opened SPR-10677 and commented
When use
jdbcTemplate.batchUpdate(String[] scripts)
if the update breaks anUncategorizedSQLException
is thrown.The
UncategorizedSQLException.getSql()
does not contains the sql that generate the error but the firstscripts[]
element.Affects: 3.2.3
Attachments:
Referenced from: commits 6a3a361, 2abec6f
The text was updated successfully, but these errors were encountered: