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 的两个 语句块将导致此错误。可能原因:
- java 映射器接口中的方法重载,如@Lucky
所述
- 在一个或多个映射器 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.properies
和 mybatis-config.xml
中定义了 mybatis.mapper-locations
时,也会发生这种情况
我在服务器启动时注册映射器 类 时抛出了以下错误消息,
[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 的两个 语句块将导致此错误。可能原因:
- java 映射器接口中的方法重载,如@Lucky 所述
- 在一个或多个映射器 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.properies
和 mybatis-config.xml
mybatis.mapper-locations
时,也会发生这种情况