apache/shardingsphere · error · SQLFeatureNotSupportedException

moveToCurrentRow

Error message

moveToCurrentRow

What it means

moveToCurrentRow() — returning from the insert row to the previously current row — throws SQLFeatureNotSupportedException in the SQL Federation ResultSet. It only exists in the updatable-cursor model, which federation deliberately does not implement; the method is final and always throws.

Source

Thrown at kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/AbstractUnsupportedOperationSQLFederationResultSet.java:125

    
    @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");
    }
    
    @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

View on GitHub (pinned to e952770a21)

Solutions

  1. Remove the insert-row sequence entirely and use explicit INSERT statements, which removes the need for moveToCurrentRow()
  2. Re-execute the query to obtain a fresh ResultSet after inserts instead of repositioning a cursor
  3. Mark federation datasources read-only in editing tools so this code path is never exercised

Example fix

// before
rs.insertRow();
rs.moveToCurrentRow();

// after
// insert via PreparedStatement, then:
try (ResultSet rs2 = stmt.executeQuery(sql)) { /* continue iteration */ }
Defensive patterns

Strategy: validation

Validate before calling

if (rs.getConcurrency() != ResultSet.CONCUR_UPDATABLE) {
    // moveToCurrentRow() unsupported: re-execute the query after inserts
}

Type guard

private boolean isUpdatable(final ResultSet rs) throws SQLException {
    return rs.getConcurrency() == ResultSet.CONCUR_UPDATABLE;
}

Try / catch

try {
    rs.moveToCurrentRow();
} catch (final SQLFeatureNotSupportedException e) {
    rs = stmt.executeQuery(sql); // fresh forward-only result set
}

Prevention

When it happens

Trigger: Calling rs.moveToCurrentRow() after an insert-row sequence (or to resume iteration after moveToInsertRow) on a federated ResultSet.

Common situations: Post-insert cursor restoration in updatable-result-set code; editors that toggle between insert mode and normal browsing; typically the second failure in a chain that began with moveToInsertRow()/insertRow() being called on a federation connection.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/04d55008282932e6. Report an issue: GitHub.