{"record":{"id":"6e07a3704b8a17d5","repo":"mybatis/mybatis-3","slug":"name-already-contains-key-key","errorCode":null,"errorMessage":"name + \" already contains key \" + key","messagePattern":"name \\+ \" already contains key \" \\+ key","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/session/Configuration.java","lineNumber":1158,"sourceCode":"     * function arguments are 1st is saved value and 2nd is target value.\n     *\n     * @param conflictMessageProducer\n     *          A function for producing a conflict error message\n     *\n     * @return a conflict error message\n     *\n     * @since 3.5.0\n     */\n    public StrictMap<V> conflictMessageProducer(BiFunction<V, V, String> conflictMessageProducer) {\n      this.conflictMessageProducer = conflictMessageProducer;\n      return this;\n    }\n\n    @Override\n    @SuppressWarnings(\"unchecked\")\n    public V put(String key, V value) {\n      if (containsKey(key)) {\n        throw new IllegalArgumentException(name + \" already contains key \" + key\n            + (conflictMessageProducer == null ? \"\" : conflictMessageProducer.apply(super.get(key), value)));\n      }\n      if (key.contains(\".\")) {\n        final String shortKey = getShortName(key);\n        if (super.get(shortKey) == null) {\n          super.put(shortKey, value);\n        } else {\n          super.put(shortKey, (V) AMBIGUITY_INSTANCE);\n        }\n      }\n      return super.put(key, value);\n    }\n\n    @Override\n    public boolean containsKey(Object key) {\n      if (key == null) {\n        return false;\n      }","sourceCodeStart":1140,"sourceCodeEnd":1176,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/session/Configuration.java#L1140-L1176","documentation":"Configuration.StrictMap.put() rejects duplicate full keys: every mapped statement, result map, parameter map, and sql fragment is stored in a StrictMap keyed by its fully-qualified id (namespace + '.' + id). Registering a second object with the same full name throws IllegalArgumentException with the map name, the key, and an optional producer-supplied conflict detail. This is MyBatis' guard against ambiguous statement ids.","triggerScenarios":"Two <select>/<insert>/<update>/<delete> with the same id in one mapper XML namespace; the same statement id in both an XML file and an annotated mapper interface method within one namespace; registering the same mapper resource twice (mybatis-config <mapper> entries duplicated, or Spring component scan + @MapperScan overlap); same resultMap id defined in two files with the same namespace.","commonSituations":"Merging mapper files during refactoring; copy-paste of a statement without changing its id; legacy XML mapper plus new annotation-based mapper colliding after @MapperScan is added; namespace attribute copy-pasted so two files share a namespace.","solutions":["Search all mapper XML and annotation mappers for the duplicated id shown in the message and rename one of them.","Ensure each file has a unique namespace (conventionally the fully-qualified mapper interface name).","Remove duplicate <mapper> registrations pointing at the same resource (check mybatis-config.xml and Spring's mapperLocations/@MapperScan).","If using annotations, do not duplicate an annotated method id that also exists in an XML bound to the same namespace."],"exampleFix":"// before\n<mapper namespace=\"com.acme.UserMapper\">\n  <select id=\"findById\">...</select>\n  <select id=\"findById\">...</select>\n</mapper>\n// after\n<mapper namespace=\"com.acme.UserMapper\">\n  <select id=\"findById\">...</select>\n  <select id=\"findByName\">...</select>\n</mapper>","handlingStrategy":"validation","validationCode":"// Fail fast on duplicates before adding: StrictMap already throws on put,\n// so validate your XML at startup by building the Configuration once in CI.","typeGuard":null,"tryCatchPattern":"try { sqlSessionFactory = new SqlSessionFactoryBuilder().build(config); }\ncatch (IllegalArgumentException e) { /* message shows map name + duplicate key; rename or deregister */ throw e; }","preventionTips":["One unique namespace per mapper file, matching the interface FQCN.","Do not register the same resource twice (check mybatis-config <mappers> and Spring mapperLocations).","Avoid annotating a method that already has an XML statement with the same id."],"tags":["mybatis","configuration","duplicate-key","mapper-registration"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}