baomidou/mybatis-plus · critical · IOException

Failed to parse mapping resource: '

Error message

Failed to parse mapping resource: '

What it means

Thrown by MybatisSqlSessionFactoryBean.buildSqlSessionFactory while iterating mapperLocations: if MybatisXMLMapperBuilder.parse() throws for any mapper XML resource, it is wrapped in IOException('Failed to parse mapping resource: \'' + mapperLocation + '\''). The resource path in the message identifies which mapper file failed; the cause holds the parser detail (bad statement id, duplicate mapping, invalid SQL node, missing result map, etc.).

Source

Thrown at mybatis-plus-spring/src/main/java/com/baomidou/mybatisplus/spring/MybatisSqlSessionFactoryBean.java:684

        targetConfiguration.setEnvironment(new Environment(this.environment,
            this.transactionFactory == null ? new SpringManagedTransactionFactory() : this.transactionFactory,
            this.dataSource));

        if (this.mapperLocations != null) {
            if (this.mapperLocations.length == 0) {
                LOGGER.warn(() -> "Property 'mapperLocations' was specified but matching resources are not found.");
            } else {
                for (Resource mapperLocation : this.mapperLocations) {
                    if (mapperLocation == null) {
                        continue;
                    }
                    try {
                        MybatisXMLMapperBuilder xmlMapperBuilder = new MybatisXMLMapperBuilder(mapperLocation.getInputStream(),
                            targetConfiguration, mapperLocation.toString(), targetConfiguration.getSqlFragments());
                        xmlMapperBuilder.parse();
                    } catch (Exception e) {
                        throw new IOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
                    } finally {
                        ErrorContext.instance().reset();
                    }
                    LOGGER.debug(() -> "Parsed mapper file: '" + mapperLocation + "'");
                }
            }
        } else {
            LOGGER.debug(() -> "Property 'mapperLocations' was not specified.");
        }

        final SqlSessionFactory sqlSessionFactory = this.sqlSessionFactoryBuilder.build(targetConfiguration);

        SqlHelper.FACTORY = sqlSessionFactory;

        if (globalConfig.isBanner()) {
            System.out.println(" _ _   |_  _ _|_. ___ _ |    _ ");
            System.out.println("| | |\\/|_)(_| | |_\\  |_)||_|_\\ ");
            System.out.println("     /               |         ");

View on GitHub (pinned to bf67d90747)

Solutions

  1. Open the mapper file named in the message and fix the issue described by the cause exception (duplicate id, invalid attribute, malformed XML)
  2. Run xmllint or IDE validation on all files matched by the mapperLocations pattern to catch sibling errors in the same pass
  3. Verify every <include refid=...> has a matching <sql id=...> in the same namespace (or imported namespace)
  4. Tighten the mapperLocations pattern if it is matching non-mapper XML files

Example fix

<!-- before: duplicate statement id in namespace -->
<select id="selectUser" resultType="User">SELECT * FROM user</select>
<select id="selectUser" resultType="User">SELECT * FROM users</select>
<!-- after -->
<select id="selectUser" resultType="User">SELECT * FROM user</select>
<select id="selectUsers" resultType="User">SELECT * FROM users</select>
Defensive patterns

Strategy: validation

Validate before calling

// Validate every mapper XML is well-formed and has unique statement ids before startup
for (Resource r : ctx.getResources("classpath*:mapper/**/*.xml")) {
    DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(r.getInputStream());
    // additionally parse with XPath: collect select|insert|update|delete @id per namespace and assert uniqueness
}

Try / catch

try {
    factory.getObject();
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Failed to parse mapping resource:")) {
        String file = e.getMessage().substring(e.getMessage().indexOf('\''));
        throw new IllegalStateException("Broken mapper XML " + file + ": " + e.getCause().getMessage(), e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: Configuring mapperLocations (e.g. classpath*:mapper/**/*.xml) where at least one file is invalid: unparseable XML, a <select> without a resultType/resultMap or a duplicate id within the namespace, a <include> referencing a missing sql fragment, or OGNL/#{} syntax errors.

Common situations: Merge conflicts leaving broken XML; refactoring mapper namespaces or statement ids and forgetting references; adding a new mapper with a duplicated id; empty mapper XML with wrong root element; resource patterns (classpath*: vs classpath:) pulling in unexpected files.

Understand the failure class

Related errors


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