mybatis/mybatis-3 · error · RuntimeSqlException

Error executing: {}. Cause: {}

Error message

Error executing: {}.  Cause: {}

What it means

ScriptRunner.runScript reading the whole script as one statement (the non-line-by-line path) hit an exception — SQL failure, connection error, or missing terminator check — and wraps it as RuntimeSqlException embedding the entire accumulated script text and the cause. The message doubles as the error log line via printlnError.

Source

Thrown at src/main/java/org/apache/ibatis/jdbc/ScriptRunner.java:144

  }

  private void executeFullScript(Reader reader) {
    StringBuilder script = new StringBuilder();
    try {
      BufferedReader lineReader = new BufferedReader(reader);
      String line;
      while ((line = lineReader.readLine()) != null) {
        script.append(line);
        script.append(LINE_SEPARATOR);
      }
      String command = script.toString();
      println(command);
      executeStatement(command);
      commitConnection();
    } catch (Exception e) {
      String message = "Error executing: " + script + ".  Cause: " + e;
      printlnError(message);
      throw new RuntimeSqlException(message, e);
    }
  }

  private void executeLineByLine(Reader reader) {
    StringBuilder command = new StringBuilder();
    try {
      BufferedReader lineReader = new BufferedReader(reader);
      String line;
      while ((line = lineReader.readLine()) != null) {
        handleLine(command, line);
      }
      commitConnection();
      checkForMissingLineTerminator(command);
    } catch (Exception e) {
      String message = "Error executing: " + command + ".  Cause: " + e;
      printlnError(message);
      throw new RuntimeSqlException(message, e);
    }

View on GitHub (pinned to 008069adb1)

Solutions

  1. Set sendFullScript=false (default line-by-line mode) unless the driver explicitly needs one call — most failures here are driver multi-statement limits.
  2. Capture and read the cause (RuntimeSqlException.getCause()) to see the SQLSTATE and offending position.
  3. Split the script at semicolons / enable allowMultipleStatements on drivers like MySQL when full-script mode is required.
  4. Verify the script runs as-is in a SQL client with the same driver and credentials.

Example fix

// before
ScriptRunner runner = new ScriptRunner(conn);
runner.setSendFullScript(true);
runner.runScript(new FileReader("db/all.sql")); // driver rejects multi-statement

// after
ScriptRunner runner = new ScriptRunner(conn);
runner.setSendFullScript(false);
runner.runScript(new FileReader("db/all.sql"));
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: driver must support multi-statement if full-script mode is used
try (Statement st = connection.createStatement()) {
  boolean ok = st.execute("select 1; select 2"); // throws on drivers without multi-statement support
  // if it throws, use line-by-line mode instead of sendFullScript=true
}

Try / catch

try {
  runner.runScript(reader);
} catch (RuntimeSqlException e) {
  log.error("Script failed, cause={}", e.getCause() == null ? "?" : e.getCause().toString());
  // scripts are not idempotent in general: abort, roll back the connection, do not blindly retry
  connection.rollback();
  throw e;
}

Prevention

When it happens

Trigger: ScriptRunner.setSendFullScript(true) (or the single-command path) executing a script whose single statement fails: syntax error, missing permissions, unknown table, or a JDBC driver refusing multi-statement execution in one call.

Common situations: Running schema/seed scripts in tests or migrations; drivers (e.g. Oracle, older SQL Server) that do not accept multiple statements in one execute; statements containing semicolons inside strings when using full-script mode; encoding issues corrupting the script.

Related errors


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