In JdbcTemplate.batchUpdate(String... sql), I noticed that String concatenation is used inside the BatchUpdateException catch block to construct the error message.

Current Implementation


catch (BatchUpdateException ex) {
    String batchExceptionSql = null;
    for (int i = 0; i < ex.getUpdateCounts().length; i++) {
        if (ex.getUpdateCounts()[i] == Statement.EXECUTE_FAILED) {
            // String concatenation in loop
            batchExceptionSql = appendSql(batchExceptionSql, sql[i]);
        }
    }
    if (StringUtils.hasLength(batchExceptionSql)) {
        this.currSql = batchExceptionSql;
    }
    throw ex;
}

...

private String appendSql(@Nullable String sql, String statement) {
    return (StringUtils.hasLength(sql) ? sql + "; " + statement : statement);
}

Issue

Using String concatenation in a loop creates unnecessary temporary objects. While this happens in the exception path, using StringBuilder is a standard optimization practice in Java.

Proposed Solution

Replace the concatenation logic with StringBuilder:

catch (BatchUpdateException ex) {
    int[] updateCounts = ex.getUpdateCounts();
    StringBuilder failedSql = new StringBuilder();

    int limit = Math.min(updateCounts.length, sql.length);
    for (int i = 0; i < limit; i++) {
        if (updateCounts[i] == Statement.EXECUTE_FAILED) {
            if (failedSql.length() > 0) {
                failedSql.append("; ");
            }
            failedSql.append(sql[i]);
        }
    }

    if (failedSql.length() > 0) {
        this.currSql = failedSql.toString();
    }
    throw ex;
}

Benefits

  • Reduces memory allocation during batch failures
  • Follows standard Java best practices
  • No functional changes / Fully backward compatible
  • Handles edge case where updateCounts.length < sql.length

Comment From: jher235

If this approach looks reasonable, I can submit a small PR with this change. Happy to adjust based on any feedback.

Comment From: bclozel

Please submit a PR. I'll close this issue as superseded by your upcoming PR.