apache/shardingsphere · error · SQLFeatureNotSupportedException

insertRow

Error message

insertRow

What it means

insertRow() throws SQLFeatureNotSupportedException because the federation ResultSet is read-only: it exists to return the result of an already-executed federated query, not to act as an updatable JDBC cursor. The method is marked final in the abstract class, so subclasses cannot enable it either.

Source

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

    
    @Override
    public boolean absolute(final int row) throws SQLException {
        throw new SQLFeatureNotSupportedException("absolute");
    }
    
    @Override
    public boolean relative(final int rows) throws SQLException {
        throw new SQLFeatureNotSupportedException("relative");
    }
    
    @Override
    public 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

View on GitHub (pinned to e952770a21)

Solutions

  1. Perform inserts with a normal PreparedStatement INSERT executed outside federation (federation is for queries; DML goes through the regular sharding/traffic path)
  2. If an ORM grid editor is involved, disable result-set editing for this datasource or configure the editor to generate INSERT statements
  3. Verify the statement is not being classified as a federation query; hint or rewrite it so it executes as a standard sharded statement

Example fix

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

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

Strategy: try-catch

Validate before calling

if (rs.getConcurrency() == ResultSet.CONCUR_READ_ONLY) {
    // insertRow() will throw SQLFeatureNotSupportedException: use INSERT statements
}

Type guard

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

Try / catch

try {
    rs.insertRow();
} catch (final SQLFeatureNotSupportedException e) {
    executeInsert(conn, rowValues); // statement-based fallback
}

Prevention

When it happens

Trigger: Calling rs.insertRow() after moveToInsertRow()/updateXXX() on a ResultSet produced by a federation-routed statement — i.e. attempting row insertion through the JDBC updatable-ResultSet API against ShardingSphere federation.

Common situations: Visual table editors (JTable-bound JDBC editors, SQuirreL-style grid editing) that insert via the ResultSet API; legacy code written against drivers where CREATE STATEMENT RESULT_SET_UPDATABLE works; accidentally executing an INSERT..RETURNING-style or updatable SELECT through the federation path instead of a normal write statement.

Related errors


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