prestodb/presto · error · BatchUpdateException
e.getMessage()
Error message
e.getMessage()
What it means
When executeBatch encounters a failure for one statement in the batch, it wraps the SQLException in a java.sql.BatchUpdateException, copying message, SQLState, errorCode and cause, with update counts for statements executed so far. The message shown is just the underlying failure's message re-raised as a batch exception.
Source
Thrown at presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoPreparedStatement.java:468
checkOpen();
batchValues.clear();
isBatch = false;
}
@Override
public int[] executeBatch()
throws SQLException
{
try {
int[] batchUpdateCounts = new int[batchValues.size()];
for (int i = 0; i < batchValues.size(); i++) {
try {
super.execute(getExecuteSql(statementName, batchValues.get(i)));
batchUpdateCounts[i] = getUpdateCount();
}
catch (SQLException e) {
long[] updateCounts = Arrays.stream(batchUpdateCounts).mapToLong(j -> j).toArray();
throw new BatchUpdateException(e.getMessage(), e.getSQLState(), e.getErrorCode(), updateCounts, e.getCause());
}
}
return batchUpdateCounts;
}
finally {
clearBatch();
}
}
@Override
public void setCharacterStream(int parameterIndex, Reader reader, int length)
throws SQLException
{
throw new NotImplementedException("PreparedStatement", "setCharacterStream");
}
@Override
public void setRef(int parameterIndex, Ref x)View on GitHub (pinned to 55bb57d202)
Solutions
- Inspect BatchUpdateException.getUpdateCounts() to identify which statement(s) failed.
- Log e.getCause() — the original SQLException carries the real server error detail.
- Validate parameter types/values before addBatch to reject bad rows early.
- Execute statements individually to pinpoint the failing statement when diagnosing.
Example fix
// before
ps.executeBatch();
// after
try {
ps.executeBatch();
} catch (BatchUpdateException e) {
long[] counts = e.getUpdateCounts();
LOG.error("batch failed at index {} cause: {}", counts.length, e.getCause(), e);
} Defensive patterns
Strategy: try-catch
Validate before calling
// validate each batched parameter before addBatch
for (Object p : row) {
if (p != null && !(p instanceof String || p instanceof Number || p instanceof java.sql.Date || p instanceof java.sql.Time || p instanceof java.sql.Timestamp)) {
throw new IllegalArgumentException("bad batch param type: " + p.getClass());
}
} Try / catch
try { ps.executeBatch(); } catch (BatchUpdateException e) { long[] counts = e.getUpdateCounts(); SQLException cause = (SQLException) e.getCause(); LOG.error("batch failed; executed={} sqlState={} cause={}", counts.length, e.getSQLState(), cause, e); } Prevention
- Inspect getUpdateCounts() to find the failing statement index
- Log e.getCause() for the underlying server error
- Validate parameter types/values before addBatch
- Use executeBatch in a transaction so partial results can be rolled back
When it happens
Trigger: Calling executeBatch() after addBatch()/addBatch(sql) on a PrestoPreparedStatement where any batched statement fails (e.g. syntax error, type mismatch, constraint/verification failure on statement i).
Common situations: Bulk inserts where one row's value violates a column type; partial batches where the first N statements succeeded and later ones failed — inspect getUpdateCounts() to see how far execution got.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/58ec820a14648f59.
Report an issue: GitHub.