MyBatis - Mapped Statements 集合已经包含值

MyBatis - Mapped Statements collection already contains value for

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

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

我为我的映射器接口使用了注释,但没有 xml 配置。

下面是我的UserMapper界面,

public interface UserMapper {

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

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

}

我找到了错误消息的原因。如果你有相同的方法名,那么 mybatis 会抛出 Mapped Statements collection already contains value 错误信息。所以解决方案是为不同的映射器语句使用不同的方法名称,即使方法签名不同。

所以在我的映射器接口中,方法名称第二个 getAllUsers() 名称应该是 getUserById();。如果您在任何 mapper.xml 文件中具有相同的方法名称,则会抛出相同的错误。所以对于不同的sql语句,mybatis必须有唯一的方法名或映射器命名空间,才能在运行时映射它。

可能是你的参数类型不对。像 resultType 或 resultMap ,parameterType 等...

在我的例子中,发生这种情况是因为在添加映射器后将 resultMaps 添加到配置中。

例如:

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.parse语句(方法)

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

如果解析语句有问题(在 mycase 中出现,因为语句有 @ResultMap 注释,但 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");

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

当 MyBatis 为映射器中的一个方法找到多个定义时,似乎会抛出此错误。在我的例子中,我在方法的 XML 中有 注释和定义。删除其中一个解决了问题。

出于某种原因,当我将 resultType 设置为不再存在的 class 时会抛出此错误。一旦我更新了 class,问题就解决了。不确定为什么会引发此特定错误,但如果您遇到此错误,也可以检查您的 resultTypes。

对我来说,问题不在于那个查询——它只是第一个,所以它显示了那个。 真正的问题出在类型上,我用 typeAlias 解决了这个问题。 (我错过了一个注释...)

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

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

  1. java 映射器接口中的方法重载,如@Lucky
  2. 所述
  3. 在一个或多个映射器 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>

我在搜索列表时也遇到了同样的错误。我正在使用 mybatis 。我发现在同一个映射器 xml 文件中有一个插入语句,并且我在那里使用了“sysdate”,类似于下面的语句

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

这在 myatis 的情况下似乎是错误的。所以我从java端发送了sysdate参数,问题就解决了。

当您在 appication.properiesmybatis-config.xml

中定义了 mybatis.mapper-locations 时,也会发生这种情况