{"record":{"id":"a47a1f8d6afd54bf","repo":"apache/shardingsphere","slug":"addbatch-sql-in-preparedstatement","errorCode":null,"errorMessage":"addBatch sql in PreparedStatement","messagePattern":"addBatch sql in PreparedStatement","errorType":"exception","errorClass":"SQLFeatureNotSupportedException","httpStatus":null,"severity":"error","filePath":"jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationPreparedStatement.java","lineNumber":39,"sourceCode":"\nimport java.io.Reader;\nimport java.sql.NClob;\nimport java.sql.PreparedStatement;\nimport java.sql.Ref;\nimport java.sql.ResultSet;\nimport java.sql.ResultSetMetaData;\nimport java.sql.RowId;\nimport java.sql.SQLException;\nimport java.sql.SQLFeatureNotSupportedException;\n\n/**\n * Unsupported {@code PreparedStatement} methods.\n */\npublic abstract class AbstractUnsupportedOperationPreparedStatement extends AbstractStatementAdapter implements PreparedStatement {\n    \n    @Override\n    public final void addBatch(final String sql) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"addBatch sql in PreparedStatement\");\n    }\n    \n    @Override\n    public final ResultSetMetaData getMetaData() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getMetaData\");\n    }\n    \n    @Override\n    public final void setNString(final int parameterIndex, final String x) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"setNString\");\n    }\n    \n    @Override\n    public final void setNClob(final int parameterIndex, final NClob x) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"setNClob\");\n    }\n    \n    @Override","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationPreparedStatement.java#L21-L57","documentation":"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().","triggerScenarios":"Calling ps.addBatch(\"INSERT ...\") on a ShardingSphere PreparedStatement; typical of copy-pasted Statement batching code or generic batch helpers that accept (PreparedStatement, String) pairs.","commonSituations":"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.","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()."],"exampleFix":"// before\ntry (PreparedStatement ps = conn.prepareStatement(sql)) {\n    for (Row r : rows) { ps.addBatch(sql); }\n}\n\n// after\ntry (PreparedStatement ps = conn.prepareStatement(sql)) {\n    for (Row r : rows) { ps.setInt(1, r.id); ps.addBatch(); }\n    ps.executeBatch();\n}","handlingStrategy":"validation","validationCode":"// Validate before batching: PreparedStatement takes no SQL\nif (stmt instanceof PreparedStatement) { ((PreparedStatement) stmt).addBatch(); } else { stmt.addBatch(sql); }","typeGuard":"static void addToBatch(final Statement stmt, final String sql) throws SQLException {\n    if (stmt instanceof PreparedStatement) { ((PreparedStatement) stmt).addBatch(); } else { stmt.addBatch(sql); }\n}","tryCatchPattern":null,"preventionTips":["PreparedStatement.addBatch() is always no-arg","Set parameters with setXXX before each addBatch()","Branch generic batch helpers on instanceof PreparedStatement"],"tags":["jdbc","shardingsphere","preparedstatement","batch","api-misuse"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}