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.
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.
Appendix: 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)