对项目进行重构后,启动报错,如下:
org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. The XML location is 'cn/edu/fudan/projectmanager/mapper/RepoMapper.xml'. Cause: java.lang.IllegalStateException: No typehandler found for property repoName at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:120) ~[mybatis-3.4.6.jar:3.4.6]
只能通过二分查找的方式进行错误定位,自己不知道什么地方改错了。
首先日志中说的是Mapper.xml的问题,但是xml中的变更是无关紧要的变更。回退之后报错继续。
其中提到的RepoName这个属性报错。回到Repo类中的定义,乍一看这个属性也没有问题。尝试了回退所以Repo类中的变更,错误消失。至此,问题定位在了这个类中!
重新思考日志中的提示:关键点在于repoName这个属性,关于这个属性的变更如下:
public Repo(RepoDTO repoDTO, String importAccountUuid) throws WrongRepoInfoException {
...
if (repoDTO.getRepoName() == null || "".equals(repoName)) {
this.repoName = repoDTO.getUrl().substring(repoDTO.getUrl().lastIndexOf("/")).replace("/", "") + "-" + repoDTO.getBranch();
}else{
this.repoName = repoDTO.getRepoName();
}
this.url = FileUtil.trimUrl(repoDTO.getUrl());
...
}
为了提升代码的可读性,对构造函数中的赋值操作进行了private的方法抽象。
将抽象通过in line取消,也就是改成下面的版本,问题解决!
public Repo(RepoDTO repoDTO, String importAccountUuid) throws WrongRepoInfoException {
...
setRepoName(repoDTO);
this.url = FileUtil.trimUrl(repoDTO.getUrl());
...
}
private void setRepoName(RepoDTO repoDTO) {
if (repoDTO.getRepoName() == null || "".equals(repoName)) {
this.repoName = repoDTO.getUrl().substring(repoDTO.getUrl().lastIndexOf("/")).replace("/", "") + "-" + repoDTO.getBranch();
}else{
this.repoName = repoDTO.getRepoName();
}
}
总结
- 不能想当然,一定要根据报错信息定位问题。
- 重构本身没有问题,但是需要及时通过测试保证没有将系统改坏。
- 一堆提交会使得问题极难定位,控制好commit的粒度。
- mybatis对面向对象的支持不够好,尤其是对于属性的访问需要把我们预想中的大,而这在一定程度上破坏了封装特性。
- 这个问题的根本原因没有定位,下次一定。