mybatis报错“Result Maps collection already contains value for ***”

这是工作中遇到的一个问题:测试环境部署出错,报了下面的问题。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Caused by: java.lang.IllegalArgumentException: Result Maps collection already contains value for xxx.xxx.xxxRepository.BaseResultMap
	at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:802)
	at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:774)
	at org.apache.ibatis.session.Configuration.addResultMap(Configuration.java:556)
	at org.apache.ibatis.builder.MapperBuilderAssistant.addResultMap(MapperBuilderAssistant.java:217)
	at org.apache.ibatis.builder.ResultMapResolver.resolve(ResultMapResolver.java:47)
	at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:285)
	at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:252)
	at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElements(XMLMapperBuilder.java:244)
	at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:116)

检查了对应的mapper文件和java文件,已经8个多月没有修改过了。也检查了内容,没有发现重复的BaseResultMap;select中也resultMap的引用也都正确。

其实到最后发现跟代码一丁点关系都没有,是部署的时候没有删除旧版本的代码导致两个不同版本的jar同时存在,相应的mapper文件也有两个。

看了下源码,mybatis在创建SessionFactoryBean解析xml时候,会把xml中的resultMap放入到一个HashMap的子类StrictMap中,key是mapper的namespace与resultmap的id拼接成的。

StrictMap在put元素的时候,会检查map中是否已存在key。

1
2
3
4
5
public void addResultMap(ResultMap rm) {
  resultMaps.put(rm.getId(), rm);
  checkLocallyForDiscriminatedNestedResultMaps(rm);
  checkGloballyForDiscriminatedNestedResultMaps(rm);
}

Comments

comments powered by Disqus