apache/shardingsphere · error · SQLFeatureNotSupportedException
updateNClob
Error message
updateNClob
What it means
The SQL federation engine in ShardingSphere returns a read-only, forward-only ResultSet whose updater layer (AbstractUnsupportedUpdateOperationSQLFederationResultSet) deliberately rejects every JDBC row-update method. Calling updateNClob(int, NClob) throws SQLFeatureNotSupportedException because federation queries are computed in-memory from merged results and cannot be written back to the underlying shards. This mirrors how the JDBC driver reports an optional feature that is not implemented.
Source
Thrown at kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/AbstractUnsupportedUpdateOperationSQLFederationResultSet.java:394
@Override
public final void updateClob(final String columnLabel, final Reader reader) throws SQLException {
throw new SQLFeatureNotSupportedException("updateClob");
}
@Override
public final void updateClob(final int columnIndex, final Reader reader, final long length) throws SQLException {
throw new SQLFeatureNotSupportedException("updateClob");
}
@Override
public final void updateClob(final String columnLabel, final Reader reader, final long length) throws SQLException {
throw new SQLFeatureNotSupportedException("updateClob");
}
@Override
public final void updateNClob(final int columnIndex, final NClob nClob) throws SQLException {
throw new SQLFeatureNotSupportedException("updateNClob");
}
@Override
public final void updateNClob(final String columnLabel, final NClob nClob) throws SQLException {
throw new SQLFeatureNotSupportedException("updateNClob");
}
@Override
public final void updateNClob(final int columnIndex, final Reader reader) throws SQLException {
throw new SQLFeatureNotSupportedException("updateNClob");
}
@Override
public final void updateNClob(final String columnLabel, final Reader reader) throws SQLException {
throw new SQLFeatureNotSupportedException("updateNClob");
}
@OverrideView on GitHub (pinned to e952770a21)
Solutions
- Do not use ResultSet updater methods on federation results; issue a separate UPDATE statement against the target table instead.
- Rewrite the query so it is not routed to the federation engine (e.g. make it a single-shard query) if you must use updatable ResultSets.
- Configure or exclude the SQL federation feature (sql_federation: false / remove SQLFederationRule) for statements where updater methods are required.
- Catch SQLFeatureNotSupportedException and fall back to a plain UPDATE via PreparedStatement in generic JDBC utility code.
Example fix
// before
ResultSet rs = stmt.executeQuery("SELECT t.*, u.name FROM t JOIN u ON ... federated");
rs.next();
rs.updateNClob(1, nclob); // SQLFeatureNotSupportedException
rs.updateRow();
// after
ResultSet rs = stmt.executeQuery("SELECT ... federated");
rs.next();
String sql = nclob == null ? "UPDATE t SET clob_col = NULL WHERE id = ?" : "UPDATE t SET clob_col = ? WHERE id = ?";
try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setNClob(1, nclob); ps.setLong(2, id); ps.executeUpdate(); } Defensive patterns
Strategy: try-catch
Validate before calling
if (rs.getConcurrency() != ResultSet.CONCUR_UPDATABLE) { throw new IllegalStateException("ResultSet is not updatable; use UPDATE statement"); } Try / catch
try { rs.updateNClob(1, nclob); } catch (final SQLFeatureNotSupportedException ex) { /* fall back to PreparedStatement UPDATE */ } Prevention
- Never call ResultSet updater methods on SQL federation results; treat them as read-only.
- Check rs.getConcurrency() and rs.getType() before using updater APIs.
- Write updates as explicit UPDATE statements via PreparedStatement.
When it happens
Trigger: Executing a federated query (cross-shard JOIN, subquery, or UNION routed through the SQL federation engine) and then calling rs.updateNClob(columnIndex, nClob) on the returned ResultSet, e.g. before rs.updateRow().
Common situations: ORM frameworks (Hibernate, MyBatis with updatable result maps, Spring Data JDBC) that auto-detect updatable ResultSets; code ported from a native MySQL/PostgreSQL driver where NClob updates worked; generic JDBC tooling that calls updateNClob when getConcurrency() is misreported.
Related errors
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/1a7d1111a28518ab.
Report an issue: GitHub.