mybatis/mybatis-3 · error · ExecutorException

Error preparing statement. Cause: {}

Error message

Error preparing statement.  Cause: {}

What it means

A non-SQLException error occurred while preparing a java.sql.Statement: instantiateStatement(connection) plus timeout/fetch-size setup is wrapped, and any failure other than a raw SQLException (which is rethrown as-is) is wrapped as 'Error preparing statement' with the cause. Typical causes are illegal/unsupported timeout or fetch-size values, driver runtime errors, or reflection-style failures inside the driver.

Source

Thrown at src/main/java/org/apache/ibatis/executor/statement/BaseStatementHandler.java:99

  public ParameterHandler getParameterHandler() {
    return parameterHandler;
  }

  @Override
  public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
    ErrorContext.instance().sql(boundSql.getSql());
    Statement statement = null;
    try {
      statement = instantiateStatement(connection);
      setStatementTimeout(statement, transactionTimeout);
      setFetchSize(statement);
      return statement;
    } catch (SQLException e) {
      closeStatement(statement);
      throw e;
    } catch (Exception e) {
      closeStatement(statement);
      throw new ExecutorException("Error preparing statement.  Cause: " + e, e);
    }
  }

  protected abstract Statement instantiateStatement(Connection connection) throws SQLException;

  protected void setStatementTimeout(Statement stmt, Integer transactionTimeout) throws SQLException {
    Integer queryTimeout = null;
    if (mappedStatement.getTimeout() != null) {
      queryTimeout = mappedStatement.getTimeout();
    } else if (configuration.getDefaultStatementTimeout() != null) {
      queryTimeout = configuration.getDefaultStatementTimeout();
    }
    if (queryTimeout != null) {
      stmt.setQueryTimeout(queryTimeout);
    }
    StatementUtil.applyTransactionTimeout(stmt, queryTimeout, transactionTimeout);
  }

View on GitHub (pinned to 008069adb1)

Solutions

  1. Read the cause exception — it names the actual failing call (usually setQueryTimeout or setFetchSize with an invalid value).
  2. Fix or remove the invalid timeout/fetchSize on the statement and Configuration defaults.
  3. Upgrade or replace the JDBC driver if it throws non-SQLException errors on legal values.
  4. Verify the SQL string itself against the driver (prepare-time syntax checks surface here as SQLException with the SQL bound into ErrorContext).

Example fix

<!-- before -->
<settings>
  <setting name="defaultStatementTimeout" value="-1"/>
</settings>

<!-- after -->
<settings>
  <setting name="defaultStatementTimeout" value="30"/>
</settings>
Defensive patterns

Strategy: try-catch

Validate before calling

// validate timeout/fetchSize settings before building the SqlSessionFactory
int timeout = configuration.getDefaultStatementTimeout() == null
    ? 0 : configuration.getDefaultStatementTimeout();
if (timeout < 0) throw new IllegalStateException("defaultStatementTimeout must be >= 0");
if (configuration.getDefaultFetchSize() != null && configuration.getDefaultFetchSize() <= 0
    && !configuration.getDefaultFetchSize().equals(Integer.MIN_VALUE)) {
  throw new IllegalStateException("defaultFetchSize must be positive (or Integer.MIN_VALUE for streaming)");
}

Try / catch

try {
  return session.selectList("stmt");
} catch (PersistenceException e) {
  if (e.getMessage() != null && e.getMessage().contains("Error preparing statement")) {
    // inspect cause: invalid timeout/fetchSize or driver prepare failure; report SQL from ErrorContext
    log.error("Prepare failed for sql={} cause={}", org.apache.ibatis.executor.ErrorContext.instance().getSql(), e.getCause());
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling executor/statementHandler.prepare(...) — i.e. executing any mapped statement — where setting timeout (mappedStatement.getTimeout() or defaultStatementTimeout) or fetchSize throws a RuntimeException/Error, or the driver raises a non-SQLException during PreparedStatement creation.

Common situations: Setting timeout=-1 or another invalid value via <select timeout="..."> or defaultStatementTimeout; drivers that do not support setFetchSize values used (e.g. positive fetch size on MySQL without streaming); driver jar incompatibilities throwing runtime exceptions during prepare.

Related errors


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