MyCATApache/Mycat-Server · error · UnsupportedOperationException
holdability not supported yet
Error message
holdability not supported yet
What it means
MongoStatement validates statement options at creation time and rejects any statement whose holdability is set to a non-zero value. The MongoDB backend does not implement ResultSet holdability semantics (keeping cursors open after commit), so it fails fast with UnsupportedOperationException rather than silently ignoring the setting. The check runs in the public constructor/validation path, so construction itself throws.
Solutions
- Use the holdability-free overloads: Connection.createStatement() or createStatement(resultSetType, resultSetConcurrency) so _holdability stays 0.
- Change the caller/configuration to pass 0 (no explicit holdability) when connecting to the MongoDB backend.
- Explicitly unset holdability in ORM/datasource settings (e.g. disable resultSetHoldability options in pool/ORM config).
- If holdability is truly required, patch MongoStatement to accept and ignore or implement the holdability setting for the MongoDB backend.
- Route statements that need holdability to a backend that supports it instead of the MongoDB driver.
Example fix
// before
Statement st = conn.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
// after
Statement st = conn.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY); Defensive patterns
Strategy: try-catch
Validate before calling
// check before creating the statement
if (holdability != 0) {
throw new IllegalArgumentException(
"MongoDB backend requires holdability=0, got " + holdability);
}
Statement st = conn.createStatement(type, concurrency /*, no holdability */); Type guard
boolean isMongoBackend(Connection c) {
try { return c.getMetaData().getDatabaseProductName().toLowerCase().contains("mongo"); }
catch (SQLException e) { return false; }
} Try / catch
Statement st;
try {
st = conn.createStatement(type, concurrency, holdability);
} catch (UnsupportedOperationException e) {
st = conn.createStatement(type, concurrency); // drop holdability
} Prevention
- Always use the two-argument createStatement/prepareStatement overloads against the MongoDB backend.
- Audit ORM and connection-pool configs for explicit holdability settings.
- Document that holdability is unsupported in the Mycat MongoDB driver.
When it happens
Trigger: Calling Connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability) or prepareStatement overloads with a holdability argument other than 0 when using the MongoDB JDBC driver; passing constants like ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT.
Common situations: Application code or ORM/connection-pool configuration (e.g. MyBatis, Hibernate, DBCP statement defaults) specifies a holdability value that works on MySQL/PostgreSQL but is passed through unchanged to the Mycat MongoDB driver; porting JDBC code between backends.
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
- CallableStatement not supported
- 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/7efa63ae2d8d723a.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/backend/jdbc/mongodb/MongoStatement.java:40
private int _fetchSize = 0;
//int _maxRows = 0;
private MongoResultSet _last;
public MongoStatement(MongoConnection conn, int type, int concurrency, int holdability)
{
this._conn = conn;
this._type = type;
this._concurrency = concurrency;
this._holdability = holdability;
if (this._type != 0) {
throw new UnsupportedOperationException("type not supported yet");
}
if (this._concurrency != 0) {
throw new UnsupportedOperationException("concurrency not supported yet");
}
if (this._holdability != 0) {
throw new UnsupportedOperationException("holdability not supported yet");
}
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
throw new UnsupportedOperationException();//return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public ResultSet executeQuery(String sql) throws SQLException {
View on GitHub (pinned to 65f8d8beb7)