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");
}
@OverrideView on GitHub (pinned to e952770a21)
Solutions
- Perform inserts with a normal PreparedStatement INSERT executed outside federation (federation is for queries; DML goes through the regular sharding/traffic path)
- If an ORM grid editor is involved, disable result-set editing for this datasource or configure the editor to generate INSERT statements
- 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
- Never use the insert-row cursor API on federation datasources
- Always write via PreparedStatement INSERT
- Mark federation connections read-only in grid editors
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.