apache/shardingsphere · error · SQLFeatureNotSupportedException

` ` cannot be unwrapped as

Error message

`%s` cannot be unwrapped as `%s`

What it means

RawResultSetMetaData implements the standard JDBC Wrapper contract minimally: unwrap(iface) succeeds only when iface.isInstance(this) — i.e. only RawResultSetMetaData itself or its supertypes. Requesting any other interface (JDBC4ResultSetMetaData, driver-specific metadata, etc.) throws SQLFeatureNotSupportedException with the class names formatted into the message. Raw metadata simply does not wrap any richer implementation.

Solutions

  1. Call isWrapperFor(iface) first and skip the vendor-specific path when it returns false.
  2. Do vendor-specific metadata access on a connection that bypasses ShardingSphere, or accept the generic metadata interface only.
  3. Replace unwrap-based feature detection with SQL-level capability checks (DatabaseMetaData) that ShardingSphere forwards.

Example fix

// before
PgResultSetMetaData md = resultSet.getMetaData().unwrap(PgResultSetMetaData.class);

// after
ResultSetMetaData md = resultSet.getMetaData();
if (md.isWrapperFor(PgResultSetMetaData.class)) {
    // vendor path on a direct driver connection only
} else {
    // generic path: md.getColumnName(i), md.getColumnType(i), ...
}
Defensive patterns

Strategy: type-guard

Type guard

if (metaData.isWrapperFor(PgResultSetMetaData.class)) { ... } // only then unwrap

Try / catch

try { return metaData.unwrap(target); } catch (SQLFeatureNotSupportedException e) { /* fall back to generic ResultSetMetaData APIs */ }

Prevention

When it happens

Trigger: Calling resultSet.getMetaData().unwrap(org.postgresql.jdbc.PgResultSetMetaData.class) or unwrap(com.mysql.cj.jdbc.result.ResultSetMetaData.class) through ShardingSphere; generic framework code that tries unwrap(X) before falling back, where X is never the raw metadata class.

Common situations: Code migrated from a direct driver connection where unwrap of the driver metadata type worked; Spring/JDBC helper libraries probing for vendor-specific metadata to read vendor columns; tests asserting vendor metadata behavior through the ShardingSphere layer.

Related errors


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

Appendix: source

Thrown at infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawResultSetMetaData.java:208

                return String.class.getName();
            default:
                return Object.class.getName();
        }
    }
    
    private RawQueryResultColumnMetaData getColumnMetaData(final int column) throws SQLException {
        if (column < 1 || column > columns.size()) {
            throw new SQLException(String.format("Column index out of range: %s", column));
        }
        return columns.get(column - 1);
    }
    
    @Override
    public <T> T unwrap(final Class<T> iface) throws SQLException {
        if (isWrapperFor(iface)) {
            return iface.cast(this);
        }
        throw new SQLFeatureNotSupportedException(String.format("`%s` cannot be unwrapped as `%s`", getClass().getName(), iface.getName()));
    }
    
    @Override
    public boolean isWrapperFor(final Class<?> iface) {
        return iface.isInstance(this);
    }
}

View on GitHub (pinned to e952770a21)