alibaba/spring-ai-alibaba · error · SQLException
Not a wrapper for
Error message
Not a wrapper for <interface name>
What it means
The Connection wrapper used by H2Saver implements the JDBC Wrapper pattern: unwrap(Class<T>) returns this only if iface.isInstance(this) (i.e. the requested interface is implemented by the wrapper itself), otherwise it throws SQLException("Not a wrapper for <interface name>"). Unlike delegating wrappers, it cannot unwrap the underlying driver Connection.
Solutions
- Check isWrapperFor(iface) before calling unwrap and fall back if false.
- Obtain the underlying native connection directly from the DataSource instead of unwrapping through the saver's wrapper.
- If vendor-specific features are needed, bypass the saver's connection wrapper and use your own connection to the same H2 database.
- Catch SQLException with message prefix 'Not a wrapper for' and handle gracefully.
Example fix
// before: blind unwrap throws
JdbcConnection h2 = conn.unwrap(JdbcConnection.class); // SQLException
// after: guard first
if (conn.isWrapperFor(JdbcConnection.class)) {
JdbcConnection h2 = conn.unwrap(JdbcConnection.class);
} else { /* use generic JDBC API */ } Defensive patterns
Strategy: type-guard
Validate before calling
if (!conn.isWrapperFor(TargetConnection.class)) { /* use generic JDBC API instead */ } Type guard
boolean unwrappable(Connection c, Class<?> iface) { return c.isWrapperFor(iface); } Try / catch
try { return conn.unwrap(TargetConnection.class); }
catch (SQLException e) { if (e.getMessage().startsWith("Not a wrapper for")) return null; throw e; } Prevention
- Always call isWrapperFor before unwrap
- Avoid vendor-specific connection casts through the saver's wrapper
- Get a separate native connection from the DataSource for driver-specific features
When it happens
Trigger: Calling conn.unwrap(SomeDriverConnectionClass.class) — or isWrapperFor-driven unwrap of a native H2/driver connection interface — on the saver's wrapper connection when the wrapper does not implement that interface.
Common situations: Driver-specific code (e.g. accessing H2's JdbcConnection for vendor features) or pooling/proxy frameworks trying to unwrap the native connection and hitting the wrapper instead.
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
- Unable to load checkpoints
- Unable to load latest checkpoint
- Content Type used for store state
- Failed to clear database store
- Failed to delete item from database
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/52891de0907a64dd.
Report an issue: GitHub.
Appendix: source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/h2/H2Saver.java:646
this.loginTimeout = seconds;
}
@Override
public int getLoginTimeout() {
return loginTimeout;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
throw new SQLFeatureNotSupportedException();
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
if (iface.isInstance(this)) {
return iface.cast(this);
}
throw new SQLException("Not a wrapper for " + iface.getName());
}
@Override
public boolean isWrapperFor(Class<?> iface) {
return iface.isInstance(this);
}
}
}
View on GitHub (pinned to f82da0b50f)