{"record":{"id":"d41ee90461890fe8","repo":"apache/shardingsphere","slug":"updatexxx","errorCode":null,"errorMessage":"updateXXX","messagePattern":"updateXXX","errorType":"exception","errorClass":"SQLFeatureNotSupportedException","httpStatus":null,"severity":"error","filePath":"jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedUpdateOperationResultSet.java","lineNumber":46,"sourceCode":"import java.sql.Date;\nimport java.sql.NClob;\nimport java.sql.Ref;\nimport java.sql.ResultSet;\nimport java.sql.RowId;\nimport java.sql.SQLException;\nimport java.sql.SQLFeatureNotSupportedException;\nimport java.sql.SQLXML;\nimport java.sql.Time;\nimport java.sql.Timestamp;\n\n/**\n * Unsupported {@code ResultSet} methods.\n */\npublic abstract class AbstractUnsupportedUpdateOperationResultSet extends WrapperAdapter implements ResultSet {\n    \n    @Override\n    public final void updateNull(final int columnIndex) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"updateXXX\");\n    }\n    \n    @Override\n    public final void updateNull(final String columnLabel) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"updateXXX\");\n    }\n    \n    @Override\n    public final void updateBoolean(final int columnIndex, final boolean x) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"updateXXX\");\n    }\n    \n    @Override\n    public final void updateBoolean(final String columnLabel, final boolean x) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"updateXXX\");\n    }\n    \n    @Override","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedUpdateOperationResultSet.java#L28-L64","documentation":"ShardingSphere's driver deliberately does not support updatable ResultSets. AbstractUnsupportedUpdateOperationResultSet.updateNull(int) throws SQLFeatureNotSupportedException('updateXXX'). Read-only result sets are a documented limitation: the sharding driver merges results from multiple real ResultSets, so in-place row mutation (updateRow/insertRow model) cannot be implemented.","triggerScenarios":"Creating a statement with ResultSet.CONCUR_UPDATABLE and calling rs.updateNull(columnIndex) before rs.updateRow() — i.e. the classic JDBC positioned-update pattern.","commonSituations":"Porting desktop/J2EE-era code that edits rows via updatable ResultSet instead of UPDATE SQL; frameworks or DAO helpers that auto-detect CONCUR_UPDATABLE; the same code worked against the plain MySQL Connector/J or PostgreSQL driver before adding jdbc:shardingsphere:.","solutions":["Rewrite the positioned update as a normal UPDATE statement: UPDATE t SET col = NULL WHERE id = ? executed via PreparedStatement (this also routes correctly through sharding).","Remove ResultSet.CONCUR_UPDATABLE from your createStatement/prepareStatement calls so drivers and frameworks do not attempt the updatable path.","If in-place editing is essential for a screen/flow, connect that flow directly to the physical database driver."],"exampleFix":"// before\nstmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);\nrs = stmt.executeQuery(\"SELECT note FROM t WHERE id=1\");\nrs.next();\nrs.updateNull(1);\nrs.updateRow();\n\n// after\ntry (PreparedStatement ps = conn.prepareStatement(\"UPDATE t SET note = NULL WHERE id = ?\")) {\n    ps.setInt(1, 1);\n    ps.executeUpdate();\n}","handlingStrategy":"validation","validationCode":"DatabaseMetaData md = conn.getMetaData();\nboolean updatableOk = md.supportsResultSetConcurrency(\n        ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);\nif (!updatableOk) {\n    throw new UnsupportedOperationException(\"positioned updates unavailable; use UPDATE SQL\");\n}","typeGuard":"private static boolean canPositionUpdate(Connection c) throws SQLException {\n    try {\n        return c.getMetaData().supportsResultSetConcurrency(\n                ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);\n    } catch (SQLException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    rs.updateNull(colIdx);\n} catch (SQLFeatureNotSupportedException e) {\n    // rewrite path: fall back to UPDATE SQL\n    throw new IllegalStateException(\"Updatable ResultSet unsupported; use UPDATE SQL\", e);\n}","preventionTips":["Always create statements CONCUR_READ_ONLY unless the target driver is verified to support updatable result sets.","Standardize on SQL UPDATE statements for all writes through sharding datasources.","Add a coding-standard rule banning updateRow()/insertRow()/deleteRow() usage in sharded services.","Cover write paths with integration tests against the real (sharded) datasource before release."],"tags":["jdbc","resultset","updatable-resultset","shardingsphere","unsupported-operation"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}