jrebel-mybatisplus
jrebel-mybatisplus copied to clipboard
当Mapper类中有重载方法的时候用jrebel启动报错,而禁用本插件之后用jrebel启动则正常
示例代码:
@Mapper
public interface ExamManageMapper {
@Select("select * from exam_manage")
List<ExamManage> findAll();
@Select("select * from exam_manage")
IPage<ExamManage> findAll(Page page);
}
报错内容:
Mapped Statements collection already contains value for com.exam.mapper.ExamManageMapper.findAll.
please check com/exam/mapper/ExamManageMapper.java (best guess) and com/exam/mapper/ExamManageMapper.java (best guess)
明天验证下,不知道mybatis
会不会也出现这个问题
使用Mybatis
时,无论是否以JRebel
启动都会有上面的异常,我的建议是在Mapper
里最好不要使用方法重载
从源码中我们也可以知道statementId = mapper.type.name + method.name
。当执行mappedStatements#put
时肯定会抛出异常
public V put(String key, V value) {
if (containsKey(key)) {
throw new IllegalArgumentException(name + " already contains value for " + key
+ (conflictMessageProducer == null ? "" : conflictMessageProducer.apply(super.get(key), value)));
}
if (key.contains(".")) {
final String shortKey = getShortName(key);
if (super.get(shortKey) == null) {
super.put(shortKey, value);
} else {
super.put(shortKey, (V) new Ambiguity(shortKey));
}
}
return super.put(key, value);
}
是这样的,我使用的是github上的另外一个开源项目,项目地址是:https://github.com/YXJ2018/SpringBoot-Vue-OnlineExam ,我不使用jrebel启动,或者禁用本插件之后使用jrebel启动项目都是可以的,没有报任何错误。唯独在使用本插件之后,使用jrebel启动就报上面的错误了。楼主可下载该项目的后端代码在idea启动试一下就能看出来了。
我建了一个test类,测试了下,是可以进行重载的。都可以正常执行sql
是这样的,我使用的是github上的另外一个开源项目,项目地址是:https://github.com/YXJ2018/SpringBoot-Vue-OnlineExam ,我不使用jrebel启动,或者禁用本插件之后使用jrebel启动项目都是可以的,没有报任何错误。唯独在使用本插件之后,使用jrebel启动就报上面的错误了。楼主可下载该项目的后端代码在idea启动试一下就能看出来了。
我建了一个test类,测试了下,是可以进行重载的。都可以正常执行sql
下面是MybatisPlus重写的Configuration
com.baomidou.mybatisplus.core.MybatisConfiguration#addMappedStatement
/**
* MybatisPlus 加载 SQL 顺序:
* <p>1、加载XML中的SQL</p>
* <p>2、加载sqlProvider中的SQL</p>
* <p>3、xmlSql 与 sqlProvider不能包含相同的SQL</p>
* <p>调整后的SQL优先级:xmlSql > sqlProvider > curdSql</p>
*/
@Override
public void addMappedStatement(MappedStatement ms) {
logger.debug("addMappedStatement: " + ms.getId());
if (mappedStatements.containsKey(ms.getId())) {
/*
* 说明已加载了xml中的节点; 忽略mapper中的SqlProvider数据
*/
logger.error("mapper[" + ms.getId() + "] is ignored, because it exists, maybe from xml file");
return;
}
super.addMappedStatement(ms);
}
之所以关掉插件不报错,是因为这个类重写了addMappedStatement
方法,如果存在相同的statement-id
,直接就会忽略,而插件是对这个类进行了代理,为了实现热加载
对这个方法进行了重写,即直接调用父类的addmappedStatement
方法。
你关掉插件,启动项目应该会有类似的输出
c.b.m.core.MybatisConfiguration : mapper[ExamManageMapper.findAll] is ignored, because it exists, maybe from xml file
我也遇到了这个问题 我的mp版本是3.5.2
我也遇到了这个问题 我的mp版本是3.5.2
看我上面的回答。
我也遇到了这个问题 我的mp版本是3.5.2
看我上面的回答。
请问,是不修复这个问题吗,(虽然重载的写法本身就是坑)
我也遇到了这个问题 我的mp版本是3.5.2
看我上面的回答。
请问,是不修复这个问题吗,(虽然重载的写法本身就是坑)
目前不打算修复哦
大佬,我尝试处理了下,处理完的结果是不会reload重载的xml,正常的xml正常relaod,不会导致项目起不来,直接贴代码,看大佬是否能采纳.
ctClass.addField(CtField.make("private ArrayList __ignoreMapCache = new ArrayList();", ctClass)); //rewrite addMappedStatement String bodyStatement = ""; if (null != cp.getOrNull(Constants.MybatisConfiguration$StrictMapClass)) { bodyStatement = "{ if(__ignoreMapCache.contains($1.getId())){logger.warn(\"mapper[\" + $1.getId() + \"] reload fail, maybe it was overridden\"); return; }" + " if (mappedStatements.containsKey($1.getId()) && !isCustomResource($1.getResource())&&!reloader.isReloading()) {" + " logger.warn(\"mapper[\" + $1.getId() + \"] is ignored, because it exists , maybe from xml file or override\");" + " __ignoreMapCache.add($1.getId());" + " return;" + " }" + "mappedStatements.put($1.getId(), $1);}"; }