Mybatis 构造方法注入
最近阅读 Mybatis 3.5.8-SNAPSHOT 版本源码,在调试过程中遇到如下异常:
org.apache.ibatis.builder.BuilderException:
Error in result map 'MyEmployee.empResultMap'.
Failed to find a constructor in 'MyEmployee' by arg names [id, name, company].
堆栈信息如下:
Caused by: org.apache.ibatis.builder.BuilderException: Error in result map 'MyEmployee.empResultMap'. Failed to find a constructor in 'MyEmployee' by arg names [id, name, company]. There might be more info in debug log.
at org.apache.ibatis.mapping.ResultMap$Builder.build(ResultMap.java:134)
at org.apache.ibatis.builder.MapperBuilderAssistant.addResultMap(MapperBuilderAssistant.java:208)
at org.apache.ibatis.builder.ResultMapResolver.resolve(ResultMapResolver.java:47)
at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:348)
at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:262)
at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElements(XMLMapperBuilder.java:254)
at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:127)
... 2 more
分析异常原因,在 ResultMap.Builder 构建 ResultMap 对象时,会调用 argNamesOfMatchingConstructor() 方法检验实体类中是否存在 constructorResultMappings 集合对应的构造方法,即检验实体类构造参数的个数、参数名、参数类型是否和 constructorResultMappings 集合的长度和集合中 resultMapping 元素的 property 属性和 javaType 属性(即 mapper.xml 文件中 constructor 元素的子元素个数、子元素的 name 属性、javaType 属性)一致,如果不一致就会抛出 BuilderException。
调试发现上图 157 行代码根据实体类构造方法获得的参数名集合为 [arg0, arg1, arg2],和 constructorResultMappings 参数提供的参数名集合 [id, name, company] 不一致,因此抛出异常。
MyEmployee、MyCompany 实体类如下:
注意:MyEmployee 构造方法并没有使用 @Param 注解。
public class MyEmployee {
private Integer id;
private String name;
private MyCompany company;
// 构造方法参数并没有使用@Param注解
public MyEmployee(Integer id, String name, MyCompany company) {
this.id = id;
this.name = name;
this.company = company;
}
}
public class MyCompany {
private Integer id;
private String name;
}
MyEmployee.xml 文件如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="MyEmployee">
<resultMap id="empResultMap" type="MyEmployee">
<construc