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
- Read the nested exception (throwable cause) — it contains the driver's actual error and statement context.
- Fix the offending script: make it idempotent (CREATE TABLE IF NOT EXISTS, DROP IF EXISTS) or correct the dialect-specific syntax.
- If best-effort continuation is desired, configure the script runner with the ignore/log error handler instead of the default ThrowsErrorHandler.
- 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
- Make DDL scripts idempotent (IF NOT EXISTS / DROP IF EXISTS).
- Match script dialect to the target database and validate on a scratch schema in CI.
- If continuation is acceptable, configure a logging error handler instead of the default ThrowsErrorHandler.
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.