mybatis/mybatis-3 · error · SqlSessionException
Error: Cannot get connection. No managed session is starte
Error message
Error: Cannot get connection. No managed session is started.
What it means
SqlSessionManager delegates session lifecycle methods to a thread-local SqlSession established by startManagedSession(). getConnection() checks localSqlSession; if no managed session was started on this thread it throws SqlSessionException 'Cannot get connection. No managed session is started.' It means you used the manager's manual/managed mode API without opening a managed session first (or from a different thread than the one that started it).
Source
Thrown at src/main/java/org/apache/ibatis/session/SqlSessionManager.java:266
public int delete(String statement) {
return sqlSessionProxy.delete(statement);
}
@Override
public int delete(String statement, Object parameter) {
return sqlSessionProxy.delete(statement, parameter);
}
@Override
public <T> T getMapper(Class<T> type) {
return getConfiguration().getMapper(type, this);
}
@Override
public Connection getConnection() {
final SqlSession sqlSession = localSqlSession.get();
if (sqlSession == null) {
throw new SqlSessionException("Error: Cannot get connection. No managed session is started.");
}
return sqlSession.getConnection();
}
@Override
public void clearCache() {
final SqlSession sqlSession = localSqlSession.get();
if (sqlSession == null) {
throw new SqlSessionException("Error: Cannot clear the cache. No managed session is started.");
}
sqlSession.clearCache();
}
@Override
public void commit() {
final SqlSession sqlSession = localSqlSession.get();
if (sqlSession == null) {
throw new SqlSessionException("Error: Cannot commit. No managed session is started.");View on GitHub (pinned to 008069adb1)
Solutions
- Call sqlSessionManager.startManagedSession() (optionally with ExecutorType/autoCommit) before any lifecycle call on that thread.
- Ensure start and use happen on the same thread; for async work, start a fresh managed session inside the worker thread.
- Prefer the mapper proxy style (getMapper without managed session) so the manager opens/closes sessions per operation automatically.
Example fix
// before
Connection c = sqlSessionManager.getConnection(); // throws
// after
sqlSessionManager.startManagedSession();
try {
Connection c = sqlSessionManager.getConnection();
} finally {
sqlSessionManager.close();
} Defensive patterns
Strategy: validation
Validate before calling
if (!sqlSessionManager.isManagedSessionStarted()) {
sqlSessionManager.startManagedSession();
}
Connection c = sqlSessionManager.getConnection(); Try / catch
try { ... } catch (SqlSessionException e) { /* check 'No managed session is started' -> fix lifecycle */ throw e; } Prevention
- Encapsulate the managed-session lifecycle in one filter/interceptor template method.
- Check isManagedSessionStarted() before lifecycle calls.
- Never share a managed session across threads; ThreadLocal does not propagate.
When it happens
Trigger: Calling SqlSessionManager.getConnection() before startManagedSession() on the same thread; starting the managed session in one thread (e.g. servlet filter) and calling getConnection() in another (e.g. async task) since ThreadLocal does not propagate; calling after close() removed the thread-local.
Common situations: Integrating SqlSessionManager with custom transaction code and forgetting the start call in one code path; moving work to an Executor/thread pool where the ThreadLocal session is absent; filter ordering so the DAO runs before the session-start filter.
Related errors
- Error: Cannot clear the cache. No managed session is start
- Error: Cannot commit. No managed session is started.
- Error: Cannot close. No managed session is started.
- Error: Cannot rollback. No managed session is started.
- Unknown execution method for: {name}
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/15f9ed95cbc513bb.
Report an issue: GitHub.