apache/shardingsphere · error · SQLFeatureNotSupportedException

moveToInsertRow

Error message

moveToInsertRow

What it means

moveToInsertRow() throws SQLFeatureNotSupportedException in the SQL Federation ResultSet. The JDBC insert-row is a special cursor position only meaningful for updatable result sets; since federation results are read-only forward streams, the abstract base class rejects entering insert mode.

Source

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

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

View on GitHub (pinned to e952770a21)

Solutions

  1. Use PreparedStatement INSERT statements for new rows instead of the insert-row cursor API
  2. If a framework component issues moveToInsertRow, configure it to generate SQL inserts or point it at a non-federation datasource
  3. Review whether the query triggering federation can avoid the federation path so native driver capabilities are preserved

Example fix

// before
rs.moveToInsertRow();
rs.updateString(1, "v");
rs.insertRow();

// after
try (PreparedStatement ps = conn.prepareStatement("INSERT INTO t(c) VALUES (?)")) {
    ps.setString(1, "v");
    ps.executeUpdate();
}
Defensive patterns

Strategy: validation

Validate before calling

if (rs.getConcurrency() != ResultSet.CONCUR_UPDATABLE) {
    // moveToInsertRow() unsupported: use INSERT statements
}

Type guard

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

Try / catch

try {
    rs.moveToInsertRow();
} catch (final SQLFeatureNotSupportedException e) {
    insertViaStatement(conn, rowValues);
}

Prevention

When it happens

Trigger: Calling rs.moveToInsertRow() as the first step of the updatable-ResultSet insert pattern (moveToInsertRow -> updateXXX -> insertRow) on a federated query ResultSet.

Common situations: DB grid tools adding a new row; DAOs using insert-row mode to avoid writing INSERT SQL; code that worked against a native driver's updatable ResultSet and later ran on a ShardingSphere federation connection (e.g. after enabling federation for cross-shard queries).

Related errors


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