{"record":{"id":"4d57aa7e5403e9d0","repo":"baomidou/mybatis-plus","slug":"cannot-use-both-one-and-many-annotations-in-the","errorCode":null,"errorMessage":"Cannot use both @One and @Many annotations in the same @Result","messagePattern":"Cannot use both @One and @Many annotations in the same @Result","errorType":"exception","errorClass":"BuilderException","httpStatus":null,"severity":"error","filePath":"mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisMapperAnnotationBuilder.java","lineNumber":481,"sourceCode":"            columnPrefix = result.many().columnPrefix();\n        }\n        return columnPrefix;\n    }\n\n    private String nestedResultMapId(Result result) {\n        String resultMapId = result.one().resultMap();\n        if (resultMapId.length() < 1) {\n            resultMapId = result.many().resultMap();\n        }\n        if (!resultMapId.contains(StringPool.DOT)) {\n            resultMapId = type.getName() + StringPool.DOT + resultMapId;\n        }\n        return resultMapId;\n    }\n\n    private boolean hasNestedResultMap(Result result) {\n        if (result.one().resultMap().length() > 0 && result.many().resultMap().length() > 0) {\n            throw new BuilderException(\"Cannot use both @One and @Many annotations in the same @Result\");\n        }\n        return result.one().resultMap().length() > 0 || result.many().resultMap().length() > 0;\n    }\n\n    private String nestedSelectId(Result result) {\n        String nestedSelect = result.one().select();\n        if (nestedSelect.length() < 1) {\n            nestedSelect = result.many().select();\n        }\n        if (!nestedSelect.contains(StringPool.DOT)) {\n            nestedSelect = type.getName() + StringPool.DOT + nestedSelect;\n        }\n        return nestedSelect;\n    }\n\n    private boolean isLazy(Result result) {\n        boolean isLazy = configuration.isLazyLoadingEnabled();\n        if (result.one().select().length() > 0 && FetchType.DEFAULT != result.one().fetchType()) {","sourceCodeStart":463,"sourceCodeEnd":499,"githubUrl":"https://github.com/baomidou/mybatis-plus/blob/bf67d907478c724120bf76292da54abf9e73c2b3/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisMapperAnnotationBuilder.java#L463-L499","documentation":"Thrown by MybatisMapperAnnotationBuilder.hasNestedResultMap when a single @Result in a @Results mapping declares resultMap ids in both its @One and @Many sub-annotations. A result property can be either a single referenced object (@One) or a collection (@Many), never both, so the builder fails fast during mapper annotation parsing.","triggerScenarios":"Annotating one @Result(column = \"x\", one = @One(resultMap = \"userRM\"), many = @Many(resultMap = \"orderRM\")) — both resultMap strings non-empty triggers the check.","commonSituations":"Copy-pasting a @Result and switching @One to @Many without clearing the old attribute; evolving a to-one relation into a to-many relation and forgetting to delete the @One part.","solutions":["Decide the relationship cardinality: keep @One for a single referenced object or @Many for a collection, and delete the other sub-annotation entirely.","If both a single object and a collection are genuinely needed, model them as two separate @Result properties each with its own sub-annotation.","Rebuild and re-run so mapper parsing validates the corrected annotation."],"exampleFix":"// before\n@Results(id = \"orderRM\", value = {\n  @Result(column = \"user_id\", property = \"user\",\n          one = @One(resultMap = \"userRM\"),\n          many = @Many(resultMap = \"itemRM\"))\n})\n\n// after\n@Results(id = \"orderRM\", value = {\n  @Result(column = \"user_id\", property = \"user\", one = @One(resultMap = \"userRM\")),\n  @Result(column = \"order_id\", property = \"items\", many = @Many(resultMap = \"itemRM\"))\n})","handlingStrategy":"validation","validationCode":"// static check over @Results of every mapper method\nfor (java.lang.reflect.Method m : mapper.getMethods()) {\n    org.apache.ibatis.annotations.Results rs = m.getAnnotation(org.apache.ibatis.annotations.Results.class);\n    if (rs == null) continue;\n    for (org.apache.ibatis.annotations.Result r : rs.value()) {\n        if (r.one().resultMap().length() > 0 && r.many().resultMap().length() > 0) {\n            throw new IllegalStateException(m + \" uses both @One and @Many resultMaps\");\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"Catch BuilderException during mapper parsing; locate the @Result named by the stack trace's mapper method and split into two properties.","preventionTips":["Model to-one and to-many relations as separate properties from the start.","When changing @One to @Many, delete the unused sub-annotation."],"tags":["mybatis","mybatis-plus","annotation","result-map","mapping"],"backgroundTag":null,"analyzedSha":"bf67d907478c724120bf76292da54abf9e73c2b3","analyzedAt":"2026-08-14T15:17:09.543Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}