{"record":{"id":"33233471faabd447","repo":"baomidou/mybatis-plus","slug":"a-mapper-element-may-only-specify-a-url-resource","errorCode":null,"errorMessage":"A mapper element may only specify a url, resource or class, but not more than one.","messagePattern":"A mapper element may only specify a url, resource or class, but not more than one\\.","errorType":"exception","errorClass":"BuilderException","httpStatus":null,"severity":"error","filePath":"mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisXMLConfigBuilder.java","lineNumber":418,"sourceCode":"                if (resource != null && url == null && mapperClass == null) {\n                    ErrorContext.instance().resource(resource);\n                    try (InputStream inputStream = Resources.getResourceAsStream(resource)) {\n                        XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource,\n                            configuration.getSqlFragments());\n                        mapperParser.parse();\n                    }\n                } else if (resource == null && url != null && mapperClass == null) {\n                    ErrorContext.instance().resource(url);\n                    try (InputStream inputStream = Resources.getUrlAsStream(url)) {\n                        XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url,\n                            configuration.getSqlFragments());\n                        mapperParser.parse();\n                    }\n                } else if (resource == null && url == null && mapperClass != null) {\n                    Class<?> mapperInterface = Resources.classForName(mapperClass);\n                    configuration.addMapper(mapperInterface);\n                } else {\n                    throw new BuilderException(\n                        \"A mapper element may only specify a url, resource or class, but not more than one.\");\n                }\n            }\n        }\n    }\n\n    private boolean isSpecifiedEnvironment(String id) {\n        if (environment == null) {\n            throw new BuilderException(\"No environment specified.\");\n        }\n        if (id == null) {\n            throw new BuilderException(\"Environment requires an id attribute.\");\n        }\n        return environment.equals(id);\n    }\n\n    private static Configuration newConfig(Class<? extends Configuration> configClass) {\n        try {","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/baomidou/mybatis-plus/blob/bf67d907478c724120bf76292da54abf9e73c2b3/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisXMLConfigBuilder.java#L400-L436","documentation":"Thrown by mappersElement when a <mapper> element in mybatis-config.xml specifies none or several of the attributes url, resource, and class. The parser handles the three single-attribute combinations explicitly (resource only, url only, class only); everything else — including two or three attributes set, or none — falls into the final else branch and throws.","triggerScenarios":"<mapper resource=\"mappers/User.xml\" class=\"com.example.UserMapper\"/> (two attributes), or an empty <mapper/> with no attributes.","commonSituations":"Adding a class attribute while a resource attribute already exists; templating mistakes producing empty <mapper/> elements; misunderstanding that one element registers exactly one mapper.","solutions":["Split into separate <mapper> elements, each with exactly one attribute: <mapper resource=\"...\"/>, <mapper url=\"...\"/>, or <mapper class=\"...\"/>.","For bulk registration prefer <package name=\"com.example.mapper\"/> to scan a whole package.","Remove empty <mapper/> elements left by templating."],"exampleFix":"<!-- before -->\n<mappers>\n  <mapper resource=\"mapper/UserMapper.xml\" class=\"com.example.mapper.UserMapper\"/>\n</mappers>\n\n<!-- after -->\n<mappers>\n  <mapper resource=\"mapper/UserMapper.xml\"/>\n  <mapper class=\"com.example.mapper.OtherMapper\"/>\n</mappers>","handlingStrategy":"validation","validationCode":"// each <mapper> must carry exactly one of resource/url/class\norg.w3c.dom.NodeList ms = doc.getElementsByTagName(\"mapper\");\nfor (int i = 0; i < ms.getLength(); i++) {\n    org.w3c.dom.Element el = (org.w3c.dom.Element) ms.item(i);\n    int attrs = Stream.of(\"resource\", \"url\", \"class\").map(a -> el.hasAttribute(a) ? 1 : 0)\n        .mapToInt(Integer::intValue).sum();\n    if (attrs != 1) throw new IllegalStateException(\"<mapper> must have exactly one of resource/url/class: \" + el);\n}","typeGuard":null,"tryCatchPattern":"Catch BuilderException 'A mapper element may only specify a url, resource or class'; split the offending element into one-attribute elements.","preventionTips":["One attribute per <mapper> element by convention.","Use <package> for bulk interface registration."],"tags":["mybatis","mybatis-plus","xml-config","mappers","configuration"],"backgroundTag":null,"analyzedSha":"bf67d907478c724120bf76292da54abf9e73c2b3","analyzedAt":"2026-08-14T15:17:09.543Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}