MyBatis - Mapped Statements collection already contains value for
Asked Answered
E

9

11

I had the following error messages thrown when registering the mapper classes on my server startup,

[artifact:mvn] 2016-05-07 11:39:21,708 [ERROR] org.mybatis.spring.mapper.MapperFactoryBean - Error while adding the mapper 'interface com.sample.mappers.UserMapper' to configuration.
[artifact:mvn] java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.sample.mappers.UserMapper.getAllUsers
[artifact:mvn]  at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:802)
[artifact:mvn]  at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:774)
[artifact:mvn]  at org.apache.ibatis.session.Configuration.addMappedStatement(Configuration.java:598)
[artifact:mvn]  at org.apache.ibatis.builder.MapperBuilderAssistant.addMappedStatement(MapperBuilderAssistant.java:300)
[artifact:mvn]  at org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parseStatement(MapperAnnotationBuilder.java:313)
[artifact:mvn]  at org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parse(MapperAnnotationBuilder.java:128)
[artifact:mvn]  at org.apache.ibatis.binding.MapperRegistry.addMapper(MapperRegistry.java:72)
[artifact:mvn]  at org.apache.ibatis.session.Configuration.addMapper(Configuration.java:671)
[artifact:mvn]  at org.mybatis.spring.mapper.MapperFactoryBean.checkDaoConfig(MapperFactoryBean.java:81)
[artifact:mvn]  at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44)

I used annotations for my mapper interfaces and there's no xml configuration.

Below is my UserMapper interface,

public interface UserMapper {

  @Select("SELECT  * FROM customer")
  List<User> getAllUsers();

  @Select("SELECT * FROM customer where userId = #{userId} ")
  List<User> getAllUsers(Long userId);

}
Emylee answered 7/5, 2016 at 7:31 Comment(0)
E
22

I found out the cause of the error message. If you have the same method name, then mybatis throws the Mapped Statements collection already contains value error message. So the solution is to have different method names for different mapper statements even if the method signatures are different.

So In my mapper interface the method names second getAllUsers() name should be getUserById();. The same error is thrown if you have the same method name in any of the mapper.xml files. So it is mandatory to have unique method names or mapper namespace for different sql statements for mybatis to map this at runtime.

Emylee answered 7/5, 2016 at 7:31 Comment(0)
T
2

In my case, the occurance was due to resultMaps were added to the Configuration after addition of mapper.

Eg:

Configuration configuration = new Configuration(environment);
configuration.addMappers("com.hemant.data.mapper");
configuration.addResultMap(getResultMapForRoles(configuration));

If we observe MyBatis source code, then on configuration.addMappers(..) ..... parse() is executed. org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parse() org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parseStatement(Method)

for (Method method : methods) {
        try {
          // issue #237
          if (!method.isBridge()) {
            parseStatement(method);
          }
        } catch (IncompleteElementException e) {
          configuration.addIncompleteMethod(new MethodResolver(this, method));
        }
      }

If there is an issue with parsing the statement (which occured in mycase as the statement had @ResultMap annotation, but resultMap wasn't provided to configuration.), the method is added in INCOMPLETE_METHODS in configuration which later raises the exception.

@Select("select role_id, role_name, allowed_actions::bigint, denied_actions::bigint from acm_role")
    @ResultMap("com.hemant.data.mapper.RoleMapper." + PermissionDBHook.ROLE_MAP)
    public List<Role> getAllRoles();

On adding resultMap to configuration before mapper, solved it

   Configuration configuration = new Configuration(environment);
   //Hemant - result map should be added before mappers
   configuration.addResultMap(getResultMapForRoles(configuration));
   configuration.addMappers("com.hemant.data.mapper");
Tearing answered 20/2, 2017 at 11:18 Comment(0)
C
1

This answer is not directly relevant to the question, but could be useful for others facing a similar error:

This error seems to be thrown when MyBatis finds multiple definitions for one of the methods in the mapper. In my case, I had both the Annotation and a definition in the XML for a method. Removing one of these resolved the issue.

Choreographer answered 8/11, 2017 at 16:9 Comment(0)
S
1

For some reason this error was thrown when I had a resultType set to a class that no longer existed. Once I updated the class, the problem was resolved. Not sure why this particular error was thrown, but perhaps check your resultTypes as well if you come across this.

Soda answered 27/6, 2018 at 4:9 Comment(0)
R
1

Mapped Statements collection already contains value for com.sample.mappers.UserMapper...

Two statement blocks with the same id will result in this error. Possible cause:

  1. java method overloading in mapper interfaces, as stated by @Lucky
  2. There are two statement blocks that use the same id in the same namespace of one or more mapper xml files.

The id findAllId in namespace com.example.UserMapper should be unique.

<mapper namespace="com.example.UserMapper">
 <select id="findAllId" resultType="java.lang.Integer">
    SELECT id FROM User
  </select>
</mapper>
Raconteur answered 6/4, 2021 at 9:51 Comment(0)
T
0

For me the problem was not with that query - it was just the first, so it shows that one. The real problem was with a type, that I resolved with a typeAlias. (I missed an annotation...)

Terreverte answered 14/11, 2019 at 14:8 Comment(0)
I
0

I also got the same error while searching a list . I was using mybatis . I found that there is an insert statement in the same mapper xml file and there I was using "sysdate" , something like the below statement

insert into tablename(id,created_time) values (#{id},sysdate)

which seems to be wrong in case of myatis. So I sent the sysdate parameter from java end, and the issue got resolved.

Indivertible answered 14/11, 2021 at 6:54 Comment(0)
A
0

This also happens when you have mybatis.mapper-locations defined in your appication.properies and in your mybatis-config.xml

Aureaaureate answered 17/3, 2022 at 13:43 Comment(0)
F
-1

Maybe your parameter type is wrong. like resultType or resultMap ,parameterType etc...

Flung answered 15/2, 2017 at 3:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.