baomidou/mybatis-plus · error · SQLException

Execute {} fail.

Error message

Execute {} fail. 

What it means

ThrowsErrorHandler is the default error handler for DdlHelper's script runner: when executing a SQL script file throws, it rethrows the cause wrapped in SQLException('Execute <sqlFile> fail. '). The message intentionally names the script file; the real reason (syntax error, missing table, constraint violation) is the nested throwable. Aborting is the point — this handler '中断后续文件执行' (stops subsequent files).

Source

Thrown at mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/ddl/DdlScriptErrorHandler.java:66

        public static final Log log = LogFactory.getLog(PrintlnLogErrorHandler.class);

        @Override
        public void handle(String sqlFile, Exception throwable) {
            log.error("run script sql:" + sqlFile + ", error: ", throwable);
        }
    }

    /**
     * 抛出错误 (中断后续文件执行)
     */
    class ThrowsErrorHandler implements DdlScriptErrorHandler {

        public static final ThrowsErrorHandler INSTANCE = new ThrowsErrorHandler();

        @Override
        public void handle(String sqlFile, Exception throwable) throws SQLException {
            throw new SQLException("Execute " + sqlFile + " fail. ", throwable);
        }

    }

}


View on GitHub (pinned to bf67d90747)

Solutions

  1. Read the nested exception (throwable cause) — it contains the driver's actual error and statement context.
  2. Fix the offending script: make it idempotent (CREATE TABLE IF NOT EXISTS, DROP IF EXISTS) or correct the dialect-specific syntax.
  3. If best-effort continuation is desired, configure the script runner with the ignore/log error handler instead of the default ThrowsErrorHandler.
  4. Verify statement delimiters and script encoding match the runner's expectations.

Example fix

-- before: fails on re-run -> SQLException('Execute schema.sql fail.')
CREATE TABLE t_user (id BIGINT PRIMARY KEY, name VARCHAR(64));

-- after: idempotent DDL (MySQL example)
CREATE TABLE IF NOT EXISTS t_user (id BIGINT PRIMARY KEY, name VARCHAR(64));
Defensive patterns

Strategy: try-catch

Validate before calling

if (!Files.exists(scriptPath) || Files.size(scriptPath) == 0) {
    throw new IllegalStateException("missing or empty DDL script: " + scriptPath);
}

Try / catch

try {
    ddlScriptRunner.execute(sqlFile);
} catch (SQLException e) {
    Throwable cause = e.getCause(); // driver-level reason for the failing statement
    throw new IllegalStateException("DDL script " + sqlFile + " failed: " + cause, e);
}

Prevention

When it happens

Trigger: DdlScriptRunner (or DdlHelper.runScript) executing .sql files where any statement fails: invalid SQL for the target dialect, missing privileges, object already exists (scripts not idempotent), or wrong delimiters/statement splitting for procedures. With the default throws-error-handler the first failure aborts the run.

Common situations: Running schema migrations at startup against a partially-initialized schema (tables already exist); scripts written for MySQL executed on PostgreSQL; missing DELIMITER handling for stored routines; CI runs without Flyway/Liquibase idempotency conventions.

Related errors


AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14). Data as JSON: /api/errors/3f4853e4f57e1ff2. Report an issue: GitHub.