apache/shardingsphere · error · SQLFeatureNotSupportedException
addBatch sql in PreparedStatement
Error message
addBatch sql in PreparedStatement
What it means
SQLFeatureNotSupportedException('addBatch sql in PreparedStatement') thrown by AbstractUnsupportedOperationPreparedStatement.addBatch(String). The JDBC specification requires PreparedStatement.addBatch(String) to throw, because a PreparedStatement is created from one fixed SQL string; batching raw SQL belongs to Statement.addBatch. ShardingSphere marks the override final and implements only the no-arg addBatch().
Source
Thrown at jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationPreparedStatement.java:39
import java.io.Reader;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
/**
* Unsupported {@code PreparedStatement} methods.
*/
public abstract class AbstractUnsupportedOperationPreparedStatement extends AbstractStatementAdapter implements PreparedStatement {
@Override
public final void addBatch(final String sql) throws SQLException {
throw new SQLFeatureNotSupportedException("addBatch sql in PreparedStatement");
}
@Override
public final ResultSetMetaData getMetaData() throws SQLException {
throw new SQLFeatureNotSupportedException("getMetaData");
}
@Override
public final void setNString(final int parameterIndex, final String x) throws SQLException {
throw new SQLFeatureNotSupportedException("setNString");
}
@Override
public final void setNClob(final int parameterIndex, final NClob x) throws SQLException {
throw new SQLFeatureNotSupportedException("setNClob");
}
@OverrideView on GitHub (pinned to e952770a21)
Solutions
- Use the no-arg ps.addBatch() after setXXX(...) each iteration — ShardingSpherePreparedStatement implements it.
- If you must batch heterogeneous raw SQL strings, create a Statement (conn.createStatement()) and use its addBatch(String).
- Fix generic helpers to branch: Statement -> addBatch(sql), PreparedStatement -> addBatch().
Example fix
// before
try (PreparedStatement ps = conn.prepareStatement(sql)) {
for (Row r : rows) { ps.addBatch(sql); }
}
// after
try (PreparedStatement ps = conn.prepareStatement(sql)) {
for (Row r : rows) { ps.setInt(1, r.id); ps.addBatch(); }
ps.executeBatch();
} Defensive patterns
Strategy: validation
Validate before calling
// Validate before batching: PreparedStatement takes no SQL
if (stmt instanceof PreparedStatement) { ((PreparedStatement) stmt).addBatch(); } else { stmt.addBatch(sql); } Type guard
static void addToBatch(final Statement stmt, final String sql) throws SQLException {
if (stmt instanceof PreparedStatement) { ((PreparedStatement) stmt).addBatch(); } else { stmt.addBatch(sql); }
} Prevention
- PreparedStatement.addBatch() is always no-arg
- Set parameters with setXXX before each addBatch()
- Branch generic batch helpers on instanceof PreparedStatement
When it happens
Trigger: Calling ps.addBatch("INSERT ...") on a ShardingSphere PreparedStatement; typical of copy-pasted Statement batching code or generic batch helpers that accept (PreparedStatement, String) pairs.
Common situations: Refactoring legacy Statement batching into PreparedStatement code without removing the sql argument; generic DAO base classes calling addBatch(sql) for all statement types; JDBC tutorials' Statement examples reused verbatim.
Related errors
- executeQuery with SQL for PreparedStatement
- executeUpdate with SQL for PreparedStatement
- setFetchSize
- getMetaData
- setNString
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/a47a1f8d6afd54bf.
Report an issue: GitHub.