{"record":{"id":"c53e2387d6499644","repo":"apache/shardingsphere","slug":"preparecall","errorCode":null,"errorMessage":"prepareCall","messagePattern":"prepareCall","errorType":"exception","errorClass":"SQLFeatureNotSupportedException","httpStatus":null,"severity":"error","filePath":"jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationConnection.java","lineNumber":44,"sourceCode":"import java.sql.Clob;\nimport java.sql.Connection;\nimport java.sql.NClob;\nimport java.sql.SQLException;\nimport java.sql.SQLFeatureNotSupportedException;\nimport java.sql.SQLXML;\nimport java.sql.Struct;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.concurrent.Executor;\n\n/**\n * Unsupported {@code Connection} methods.\n */\npublic abstract class AbstractUnsupportedOperationConnection extends WrapperAdapter implements Connection {\n    \n    @Override\n    public final CallableStatement prepareCall(final String sql) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"prepareCall\");\n    }\n    \n    @Override\n    public final CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"prepareCall\");\n    }\n    \n    @Override\n    public final CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"prepareCall\");\n    }\n    \n    @Override\n    public final String nativeSQL(final String sql) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"nativeSQL\");\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/AbstractUnsupportedOperationConnection.java#L26-L62","documentation":"ShardingSphere's JDBC driver does not implement the java.sql.Connection method prepareCall (creating a CallableStatement for invoking database stored procedures). The abstract base class AbstractUnsupportedOperationConnection, which ShardingSphereConnection extends, overrides it as final and unconditionally throws SQLFeatureNotSupportedException. ShardingSphere routes and shards SQL statements, and stored-procedure call syntax is not part of its supported routing/parsing model, so all three prepareCall overloads are permanently unsupported. The exception is thrown the moment the method is invoked on any connection produced by the ShardingSphere Driver.","triggerScenarios":"Calling Connection.prepareCall(...) with any argument combination on a Connection obtained from a ShardingSphere DataSource (jdbc:shardingsphere:... URL).","commonSituations":"Porting an existing application that uses stored procedures (e.g. {call some_proc(?)}) to ShardingSphere; ORM frameworks (Hibernate/JPA with stored-procedure queries, MyBatis callable statements) that call prepareCall behind the scenes; connection-pool validation or monitoring tools that probe CallableStatement support.","solutions":["Replace the stored-procedure call with plain SQL that ShardingSphere can route (rewrite the procedure logic as normal INSERT/SELECT statements, or move the logic into the application layer).","If the procedure must run, obtain a raw driver connection for that operation: create a separate, non-ShardingSphere DataSource pointing at the target database and call prepareCall on it.","If you only need the underlying database's CallableStatement, unwrap it: connection.unwrap(FooConnection.class).prepareCall(sql) (works only when the connection is not heavily wrapped and the native driver supports it).","Check the ShardingSphere version/release notes for stored-function/procedure support before upgrading, as this has been a long-standing unsupported area."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"boolean supportsOp = false;\ntry {\n    connection.getMetaData(); // connection is alive\n    // JDBC has no capability flag for individual methods; probe once per JVM:\n    supportsOp = probeSupport(connection); // reflective/one-time guarded call\n} catch (final SQLException ignored) {\n}\n// Simpler and recommended: capability-check by driver URL\nboolean isShardingSphere = url.startsWith(\"jdbc:shardingsphere:\");\nif (isShardingSphere) {\n    // skip the unsupported call, use the alternative API path\n}","typeGuard":null,"tryCatchPattern":"try {\n    connection.prepareCall(/* args */);\n} catch (final SQLFeatureNotSupportedException e) {\n    // expected on ShardingSphere connections: fall back to supported API\n    log.debug(\"Driver does not support prepareCall, using fallback\", e);\n}","preventionTips":["Audit code and ORM config (Hibernate jpa.procedure support, MyBatis statementType=\"CALLABLE\") for stored-procedure usage before adopting ShardingSphere.","Keep a separate native DataSource for procedure calls.","Check the JDBC URL before calling optional JDBC 4 methods: connections starting with jdbc:shardingsphere: never support the lob/network-timeout/client-info/callable APIs.","Catch java.sql.SQLFeatureNotSupportedException (parent of ShardingSphere's UnsupportedSQLOperationException) around optional driver-capability calls so the application degrades gracefully."],"tags":["jdbc","shardingsphere","unsupported-operation","connection-api"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}