{"record":{"id":"12175bbcd93a1192","repo":"apache/shardingsphere","slug":"getmetadata","errorCode":null,"errorMessage":"getMetaData","messagePattern":"getMetaData","errorType":"exception","errorClass":"SQLFeatureNotSupportedException","httpStatus":null,"severity":"error","filePath":"jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationPreparedStatement.java","lineNumber":44,"sourceCode":"import java.sql.ResultSet;\nimport java.sql.ResultSetMetaData;\nimport java.sql.RowId;\nimport java.sql.SQLException;\nimport java.sql.SQLFeatureNotSupportedException;\n\n/**\n * Unsupported {@code PreparedStatement} methods.\n */\npublic abstract class AbstractUnsupportedOperationPreparedStatement extends AbstractStatementAdapter implements PreparedStatement {\n    \n    @Override\n    public final void addBatch(final String sql) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"addBatch sql in PreparedStatement\");\n    }\n    \n    @Override\n    public final ResultSetMetaData getMetaData() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getMetaData\");\n    }\n    \n    @Override\n    public final void setNString(final int parameterIndex, final String x) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"setNString\");\n    }\n    \n    @Override\n    public final void setNClob(final int parameterIndex, final NClob x) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"setNClob\");\n    }\n    \n    @Override\n    public final void setNClob(final int parameterIndex, final Reader x) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"setNClob\");\n    }\n    \n    @Override","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationPreparedStatement.java#L26-L62","documentation":"SQLFeatureNotSupportedException('getMetaData') thrown by AbstractUnsupportedOperationPreparedStatement.getMetaData(). ShardingSphere resolves the actual target database only at execution time (routing depends on bind values and sharding rules), so it cannot produce a ResultSetMetaData for a PreparedStatement before execution; the method is final and always throws. ShardingSpherePreparedStatement computes column metadata only after executing (columnLabelAndIndexMap).","triggerScenarios":"ps.getMetaData() before ps.executeQuery()/executeUpdate() on a ShardingSphere PreparedStatement. Common in frameworks that pre-render column headers from PreparedStatement metadata (report tools, table models) and in pagination code that counts result columns first.","commonSituations":"Swing/SWT table models or Excel/CSV exporters built on PreparedStatement.getMetaData; JasperReports subreports; migration from drivers with server-side prepare (PostgreSQL, Oracle) where getMetaData worked pre-execution.","solutions":["Execute the query first and call rs.getMetaData() on the returned ResultSet — ShardingSphere delegates that to the routed backend.","For exporters, switch to a lazy header model that reads metadata from row 1 / ResultSet after execution.","Catch SQLFeatureNotSupportedException and defer metadata retrieval to post-execution."],"exampleFix":"// before\nResultSetMetaData md = ps.getMetaData();\nint cols = md.getColumnCount();\nResultSet rs = ps.executeQuery();\n\n// after\nResultSet rs = ps.executeQuery();\nint cols = rs.getMetaData().getColumnCount();","handlingStrategy":"validation","validationCode":"// ShardingSphere resolves columns only after execution: read metadata from the ResultSet\n// if (!driverName.contains(\"shardingsphere\")) use ps.getMetaData(), else execute first","typeGuard":null,"tryCatchPattern":"ResultSetMetaData md;\ntry { md = ps.getMetaData(); }\ncatch (final SQLFeatureNotSupportedException e) { md = null; } // re-read from rs.getMetaData() after execute","preventionTips":["Read column metadata from ResultSet.getMetaData() after execution","Design exporters/table models lazily","Do not pre-count columns from PreparedStatement metadata"],"tags":["jdbc","shardingsphere","preparedstatement","resultsetmetadata","sql-feature-not-supported"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}