baomidou/mybatis-plus · error · BuilderException

Mapper's namespace cannot be empty

Error message

Mapper's namespace cannot be empty

What it means

While parsing a mapper XML file, the required 'namespace' attribute of the root <mapper> element was missing or empty. The namespace binds the XML statements to a mapper interface (or class) and is mandatory; without it the builder cannot register statements or resolve full statement ids.

Source

Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisXMLMapperBuilder.java:119

        if (!configuration.isResourceLoaded(resource)) {
            configurationElement(parser.evalNode("/mapper"));
            configuration.addLoadedResource(resource);
            bindMapperForNamespace();
        }
        configuration.parsePendingResultMaps(false);
        configuration.parsePendingCacheRefs(false);
        configuration.parsePendingStatements(false);
    }

    public XNode getSqlFragment(String refid) {
        return sqlFragments.get(refid);
    }

    private void configurationElement(XNode context) {
        try {
            String namespace = context.getStringAttribute("namespace");
            if (namespace == null || namespace.isEmpty()) {
                throw new BuilderException("Mapper's namespace cannot be empty");
            }
            builderAssistant.setCurrentNamespace(namespace);
            cacheRefElement(context.evalNode("cache-ref"));
            cacheElement(context.evalNode("cache"));
            parameterMapElement(context.evalNodes("/mapper/parameterMap"));
            resultMapElements(context.evalNodes("/mapper/resultMap"));
            sqlElement(context.evalNodes("/mapper/sql"));
            buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
        } catch (Exception e) {
            throw new BuilderException("Error parsing Mapper XML. The XML location is '" + resource + "'. Cause: " + e, e);
        }
    }

    private void buildStatementFromContext(List<XNode> list) {
        if (configuration.getDatabaseId() != null) {
            buildStatementFromContext(list, configuration.getDatabaseId());
        }
        buildStatementFromContext(list, null);

View on GitHub (pinned to bf67d90747)

Solutions

  1. Add the mapper interface FQCN as the namespace: <mapper namespace="com.example.mapper.UserMapper">
  2. Check the exact resource named in the error's wrapping message ('The XML location is ...') to find the offending file
  3. Tighten mapper-locations patterns so non-mapper XML files are not scanned
  4. If using code generation, fix the template so namespace is always emitted

Example fix

<!-- before -->
<mapper>
  <select id="findById" resultType="User">...</select>
</mapper>
<!-- after -->
<mapper namespace="com.example.mapper.UserMapper">
  <select id="findById" resultType="User">...</select>
</mapper>
Defensive patterns

Strategy: validation

Validate before calling

// CI check: every mapper XML must declare a non-empty namespace
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
Document d = f.newDocumentBuilder().parse(xmlFile);
Element root = d.getDocumentElement();
if (!"mapper".equals(root.getTagName()) || root.getAttribute("namespace").trim().isEmpty()) {
    throw new IllegalStateException("Missing namespace in " + xmlFile);
}

Try / catch

Not worth catching at runtime — this is a packaging defect. Catch at startup, log the resource path from the wrapping message, and fail the build/deploy.

Prevention

When it happens

Trigger: A mapper XML file whose root element is '<mapper>' with no namespace attribute, namespace="", or namespace containing only whitespace; the file is picked up via mapper-locations scanning (e.g. classpath*:mapper/*.xml).

Common situations: Hand-written or generated XML files with the namespace accidentally deleted; template placeholders (e.g. ${namespace}) left unfilled; a stray non-mapper XML file matched by an overly broad mapper-locations glob.

Related errors


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