MyCATApache/Mycat-Server · error · RuntimeException
CallableStatement not supported
Error message
CallableStatement not supported
What it means
MongoConnection.prepareCall unconditionally throws RuntimeException("CallableStatement not supported"). The MongoDB JDBC adapter in MyCat does not implement stored-procedure calls; every overload of prepareCall is a stub. Any code asking this connection for a CallableStatement will always fail.
Solutions
- Do not issue CALL / stored-procedure statements against MongoDB-backed nodes; MongoDB has no stored procedures via this adapter
- Restrict prepareCall-based data-access code paths to RDBMS backends and use prepareStatement for Mongo nodes
- If you only need it not to crash, wrap the call in try-catch for RuntimeException and fall back to prepareStatement
- Patch MongoConnection to throw java.sql.SQLFeatureNotSupportedException instead of RuntimeException so JDBC clients can detect and degrade gracefully
Example fix
// before
@Override
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency, int resultSetHoldability) throws SQLException {
throw new RuntimeException("CallableStatement not supported");
}
// after
@Override
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency, int resultSetHoldability) throws SQLException {
throw new SQLFeatureNotSupportedException("CallableStatement not supported by MongoDB backend");
} Defensive patterns
Strategy: try-catch
Validate before calling
if (conn instanceof MongoConnection || url.startsWith("jdbc:mongodb")) {
throw new UnsupportedOperationException("prepareCall is not supported for MongoDB backends; use prepareStatement");
} Try / catch
try {
CallableStatement cs = conn.prepareCall(sql);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("CallableStatement not supported")) {
// fall back to PreparedStatement-based execution
} else {
throw e;
}
} Prevention
- Never route CALL/stored-procedure statements to MongoDB data nodes
- Gate prepareCall usage behind a backend-capability check (URL scheme or connection class)
- Prefer checking DatabaseMetaData supportsStoredProcedures() before calling prepareCall
When it happens
Trigger: Calling connection.prepareCall(String), prepareCall(String,int,int), or prepareCall(String,int,int,int) on a MongoConnection obtained via MongoDriver.connect for URL scheme mongodb://.
Common situations: Configuring MyCat with a MongoDB backend JDBC node and then running SQL that the MyCat planner routes to a stored-procedure CALL statement; reusing generic JDBC data-access code (e.g. frameworks that probe prepareCall) against a Mongo backend.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- holdability not supported yet
- batch not supported
- global seq and share join and special…
- Unexpected exception
- type not supported yet
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/6d5ecdcb2cb79c08.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/backend/jdbc/mongodb/MongoConnection.java:254
public CallableStatement prepareCall(String sql) throws SQLException {
return prepareCall(sql, 0, 0, 0);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency) throws SQLException {
return prepareCall(sql, resultSetType, resultSetConcurrency, 0);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
//return null;
throw new RuntimeException("CallableStatement not supported");
}
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
return prepareStatement(sql, 0, 0, 0);
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency) throws SQLException {
return prepareStatement(sql, resultSetType, resultSetConcurrency, 0);
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency, int resultSetHoldability)View on GitHub (pinned to 65f8d8beb7)