apache/shardingsphere · error · SQLFeatureNotSupportedException
rowDeleted
Error message
rowDeleted
What it means
rowDeleted() is final in AbstractUnsupportedOperationResultSet and always throws SQLFeatureNotSupportedException. Because deletes must go through SQL statements and never through the merged cursor, the sharding ResultSet cannot report cursor-visible deletions.
Source
Thrown at jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java:140
@Override
public final void moveToCurrentRow() throws SQLException {
throw new SQLFeatureNotSupportedException("moveToCurrentRow");
}
@Override
public final boolean rowInserted() throws SQLException {
throw new SQLFeatureNotSupportedException("rowInserted");
}
@Override
public final boolean rowUpdated() throws SQLException {
throw new SQLFeatureNotSupportedException("rowUpdated");
}
@Override
public final boolean rowDeleted() throws SQLException {
throw new SQLFeatureNotSupportedException("rowDeleted");
}
@Override
public final String getCursorName() throws SQLException {
throw new SQLFeatureNotSupportedException("getCursorName");
}
@Override
public final int getHoldability() throws SQLException {
throw new SQLFeatureNotSupportedException("getHoldability");
}
@Override
public final NClob getNClob(final int columnIndex) throws SQLException {
throw new SQLFeatureNotSupportedException("getNClob");
}
@OverrideView on GitHub (pinned to e952770a21)
Solutions
- Track deletions in application state (a set of deleted keys recorded when DELETE statements execute).
- Use SQL to determine existence (SELECT ... WHERE key = ?) instead of asking the cursor.
- Remove cursor-delete flows entirely and re-query after deletes.
Example fix
// before
while (rs.next()) { if (rs.rowDeleted()) continue; ... } // throws
// after
Set<Long> deletedIds = new HashSet<>(); // maintained by your DELETE code
while (rs.next()) { if (deletedIds.contains(rs.getLong("id"))) continue; ... } Defensive patterns
Strategy: try-catch
Validate before calling
// app-side existence check replaces the cursor probe
boolean deleted = deletedIds.contains(rs.getLong("id")); Try / catch
try {
boolean deleted = rs.rowDeleted();
} catch (SQLFeatureNotSupportedException e) {
deleted = deletedIds.contains(id);
} Prevention
- Record deleted keys when issuing DELETE statements.
- Re-query instead of scanning for visible deletes.
When it happens
Trigger: Calling ResultSet.rowDeleted() on a ResultSet obtained from ShardingSphereDataSource — usually in grids that grey out rows deleted via deleteRow, or sync loops that skip rows removed since the last fetch.
Common situations: Row-filtering logic ported from single-database drivers that support updatable cursors; master-detail UIs that rely on visible-delete semantics; JDBC tutorial-derived utility classes.
Related errors
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/1bc261c2c41218af.
Report an issue: GitHub.