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");
}
@OverrideView on GitHub (pinned to e952770a21)
Solutions
- Remove the insert-row sequence entirely and use explicit INSERT statements, which removes the need for moveToCurrentRow()
- Re-execute the query to obtain a fresh ResultSet after inserts instead of repositioning a cursor
- 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
- Re-query instead of cursor-repositioning after writes
- Keep insert and read paths as separate statements
- Remove insert-row flows from shared DAO code
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.