MyBatis - Mapped Statements集合已包含值

时间:2016-05-07 07:31:10

标签: java mybatis spring-mybatis

在我的服务器启动时注册mapper类时,我抛出了以下错误消息,

[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)

我为我的mapper接口使用了注释,并且没有xml配置。

下面是我的UserMapper界面,

public interface UserMapper {

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

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

}

7 个答案:

答案 0 :(得分:12)

我找到了错误消息的原因。如果您具有相同的方法名称,则mybatis会抛出Mapped Statements collection already contains value错误消息。因此解决方案是为不同的映射器语句设置不同的方法名称,即使方法签名不同也是如此。

因此,在我的mapper界面中,方法名称第二个getAllUsers()名称应为getUserById();。如果在任何mapper.xml文件中具有相同的方法名称,则会引发相同的错误。因此,必须为mybatis的不同sql语句提供唯一的方法名称或映射器名称空间,以便在运行时映射它。

答案 1 :(得分:1)

在我的情况下,出现的原因是在添加mapper之后将resultMaps添加到Configuration中。

例如:

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

如果我们观察MyBatis源代码,那么就开启 configuration.addMappers(..)..... parse()被执行。              的 org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parse() org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parseStatement(方法)

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

如果在解析语句时遇到问题(因为语句有@ResultMap注释而在mycase中出现,但是resultMap没有提供给配置。),该方法在INCOMPLETE_METHODS中添加到配置中,后来提升了异常。

@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();

在mapper之前将resultMap添加到配置中,解决了它

   Configuration configuration = new Configuration(environment);
   //Hemant - result map should be added before mappers
   configuration.addResultMap(getResultMapForRoles(configuration));
   configuration.addMappers("com.hemant.data.mapper");

答案 2 :(得分:1)

由于某种原因,当将resultType设置为不再存在的类时,抛出此错误。更新课程后,问题就解决了。不知道为什么会引发此特定错误,但是如果遇到此错误,也许还要检查一下resultTypes。

答案 3 :(得分:1)

<块引用>

Mapped Statements 集合已经包含 com.sample.mappers.UserMapper...

两个具有相同 id 的 语句块 将导致此错误。可能的原因:

  1. mapper 接口中的 java 方法重载,如@Lucky 所述
  2. 在一个或多个映射器 xml 文件的同一命名空间中有两个使用相同 ID 的语句块。

命名空间 com.example.UserMapper 中的 id findAllId 应该是唯一的。

<mapper namespace="com.example.UserMapper">
 <select id="findAllId" resultType="java.lang.Integer">
    SELECT id FROM User
  </select>
</mapper>

答案 4 :(得分:0)

这个答案与问题没有直接关系,但对于遇到类似错误的其他人可能有用:

当MyBatis为mapper中的某个方法找到多个定义时,似乎会抛出此错误。就我而言,我有一个方法的注释和XML 中的定义。删除其中一个解决了这个问题。

答案 5 :(得分:0)

对我来说,问题不在于该查询-它只是第一个查询,因此显示了该查询。 真正的问题是类型,我用typeAlias解决了。 (我错过了注释...)

答案 6 :(得分:-1)

也许您的参数类型错误。比如resultType或resultMap,parameterType等......