mybatis报错“Result Maps collection already contains value for ***”
这是工作中遇到的一个问题:测试环境部署出错,报了下面的问题。
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。
public void addResultMap(ResultMap rm) {
resultMaps.put(rm.getId(), rm);
checkLocallyForDiscriminatedNestedResultMaps(rm);
checkGloballyForDiscriminatedNestedResultMaps(rm);
}