apache/shardingsphere · error · SQLFeatureNotSupportedException
deleteRow
Error message
deleteRow
What it means
AbstractUnsupportedOperationResultSet declares deleteRow() final and throws SQLFeatureNotSupportedException, so the sharding ResultSet never supports positioned deletes. A row in the merged result may originate from any shard, and the driver cannot reliably resolve which physical cursor row to delete.
Source
Thrown at jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java:105
@Override
public final int getRow() throws SQLException {
throw new SQLFeatureNotSupportedException("getRow");
}
@Override
public final void insertRow() throws SQLException {
throw new SQLFeatureNotSupportedException("insertRow");
}
@Override
public final void updateRow() throws SQLException {
throw new SQLFeatureNotSupportedException("updateRow");
}
@Override
public final void deleteRow() throws SQLException {
throw new SQLFeatureNotSupportedException("deleteRow");
}
@Override
public final void refreshRow() throws SQLException {
throw new SQLFeatureNotSupportedException("refreshRow");
}
@Override
public final void cancelRowUpdates() throws SQLException {
throw new SQLFeatureNotSupportedException("cancelRowUpdates");
}
@Override
public final void moveToInsertRow() throws SQLException {
throw new SQLFeatureNotSupportedException("moveToInsertRow");
}
@OverrideView on GitHub (pinned to e952770a21)
Solutions
- Issue an explicit DELETE statement with a WHERE key predicate via PreparedStatement and let ShardingSphere route it.
- Force read-only concurrency (Statement创建时 CONCUR_READ_ONLY) so frameworks never attempt positioned deletes.
- Fall back to the physical datasource connection when positioned deletes are truly required.
Example fix
// before
rs.absolute(3);
rs.deleteRow(); // throws
// after
try (PreparedStatement ps = conn.prepareStatement("DELETE FROM t WHERE id = ?")) {
ps.setLong(1, id);
ps.executeUpdate();
} Defensive patterns
Strategy: try-catch
Validate before calling
if (rs.getConcurrency() == ResultSet.CONCUR_READ_ONLY) {
// use SQL DELETE instead of rs.deleteRow()
} Type guard
boolean supportsPositionedDelete(ResultSet rs) throws SQLException {
return rs.getConcurrency() != ResultSet.CONCUR_READ_ONLY;
} Try / catch
try {
rs.deleteRow();
} catch (SQLFeatureNotSupportedException e) {
executeKeyedDelete(id);
} Prevention
- Express deletes as DELETE ... WHERE pk = ? statements.
- Disable row-editing modes in GUI/ORM components bound to the sharding datasource.
- Keep a checklist of unsupported positioned operations when onboarding the sharding driver.
When it happens
Trigger: Calling ResultSet.deleteRow() on a ResultSet produced by ShardingSphereDataSource — directly, or via generic data-editing tools/ORMs that delete through the current cursor row instead of SQL.
Common situations: GUI SQL clients or admin tools wired to the sharding URL that edit rows via positioned deletes; legacy DAO code using positioned deletes; migration from a single-DB driver that supported CONCUR_UPDATABLE.
Related errors
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/cd800009cfcec69a.
Report an issue: GitHub.