mybatis/mybatis-3 · error · SqlSessionException

Error: Cannot clear the cache. No managed session is start

Error message

Error:  Cannot clear the cache.  No managed session is started.

What it means

SqlSessionManager.clearCache() delegates to the thread-local managed session; when localSqlSession.get() returns null (no startManagedSession() on this thread) it throws SqlSessionException 'Cannot clear the cache. No managed session is started.' It is a usage-order error, not a cache problem: the local (first-level) cache belongs to a session that was never opened on this thread.

Source

Thrown at src/main/java/org/apache/ibatis/session/SqlSessionManager.java:275

  @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.");
    }
    sqlSession.commit();
  }

  @Override
  public void commit(boolean force) {
    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

  1. Open a managed session first: startManagedSession(), then clearCache(), then close() in a finally block.
  2. If you only need uncached reads, open a fresh DefaultSqlSession (SqlSessionFactory.openSession()) per read instead of clearing a shared manager.
  3. Verify thread ownership: the ThreadLocal session exists only on the starting thread.

Example fix

// before
sqlSessionManager.clearCache(); // throws
// after
sqlSessionManager.startManagedSession();
try { sqlSessionManager.clearCache(); } finally { sqlSessionManager.close(); }
Defensive patterns

Strategy: validation

Validate before calling

if (sqlSessionManager.isManagedSessionStarted()) {
  sqlSessionManager.clearCache();
}

Prevention

When it happens

Trigger: Calling clearCache() before startManagedSession(); calling it after close() (which removes the thread-local); calling from a different thread than the one holding the managed session.

Common situations: Attempt to force fresh reads by clearing the first-level cache outside a managed session; test code obtaining SqlSessionManager from Spring and calling lifecycle methods directly without the managed-session wrapper.

Related errors


AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14). Data as JSON: /api/errors/8a9f6120d18b7a2d. Report an issue: GitHub.