确认
- [X] 我的版本是最新版本, 我的版本号与 version 相同, 并且项目里无依赖冲突
- [X] 我已经在 issue 中搜索过, 确认问题没有被提出过
- [X] 我已经修改标题, 将标题中的 描述 替换为遇到的问题
当前程序版本
3.5.7
问题描述
1.我动态生成了一个Mapper,调用com.baomidou.mybatisplus.core.MybatisConfiguration.addMapper方法注册首次成功。 2.我给Mapper增加了一个接口方法,并重新创建了Class,此时先调用removeMapper移除原Mapper,再调用com.baomidou.mybatisplus.core.MybatisConfiguration.addMapper方法注册Mapper报错:Result Maps collection already contains value for com.pf.test.mapper.TbDicMapper.testMethod-Map
测试代码如下
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
@SpringBootTest
public class MybatisPlusTest {
@Autowired
private SqlSessionFactory sqlSessionFactory;
@Test
public void test() {
try {
for(int i = 0; i < 2; i++) { // 调用两次,模拟更改操作
System.out.println("第" + (i + 1) + "次注册");
Class<?> entity = createEntity();
Class<?> mapper = createMapper(entity);
MybatisConfiguration config = (MybatisConfiguration)sqlSessionFactory.getConfiguration();
// 非首次调用时由于类是重新生成的,对象不相等,所以config.getMapperRegistry().hasMapper(mapperClass)永远为false,改为通过类名称判断
Optional<Class<?>> hadOpt = config.getMapperRegistry().getMappers().stream().filter(m -> m.getName().equals(mapper.getName())).findAny();
if(hadOpt.isPresent()) {
// 已存在,移除
config.removeMapper(hadOpt.get());
}
config.addMapper(mapper);
System.out.println("\n===========================================================");
Collection<Class<?>> pmappers = config.getMapperRegistry().getMappers();
pmappers.forEach(m -> {
if(m.getName().equals(mapper.getName())) {
System.out.println(mapper + " ——> " + mapper.getName());
}
});
System.out.println("===========================================================\n");
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static Class<?> createEntity() {
return new ByteBuddy().subclass(Object.class).name("com.pf.test.entity.TestEntity")
.annotateType(AnnotationDescription.Builder.ofType(TableName.class).define("value", "test").build())
.defineProperty("name", String.class).defineProperty("cityCode", String.class)
.defineProperty("cityLevel", Integer.class).make()
.load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.WRAPPER_PERSISTENT).getLoaded();
}
private static Class<?> createMapper(Class<?> entityClass) {
return new ByteBuddy()
.makeInterface(TypeDescription.Generic.Builder.parameterizedType(BaseMapper.class, entityClass).build())
.name("com.pf.test.mapper.TbDicMapper")
.annotateType(AnnotationDescription.Builder.ofType(Mapper.class).build())
.defineMethod("testMethod",
TypeDescription.Generic.Builder
.parameterizedType(TypeDescription.ForLoadedType.of(List.class),
TypeDescription.Generic.Builder
.parameterizedType(Map.class, String.class, Object.class).build())
.build(),
Visibility.PUBLIC)
.withParameter(TypeDescription.Generic.Builder.parameterizedType(Map.class, String.class, Object.class)
.build())
.annotateParameter(AnnotationDescription.Builder.ofType(Param.class).define("value", "querys").build())
.withoutCode()
.annotateMethod(AnnotationDescription.Builder.ofType(Select.class)
.defineArray("value", new String[] { "select * from test" }).build())
.make().load(entityClass.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER_PERSISTENT)
.getLoaded();
}
}
详细堆栈日志
第1次注册
Can not find table primary key in Class: "com.pf.test.entity.TestEntity".
2024-08-27 19:43:59.754 WARN 43120 --- [ main] c.b.m.core.injector.DefaultSqlInjector : class com.pf.test.entity.TestEntity ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
===========================================================
interface com.pf.test.mapper.TbDicMapper ——> com.pf.test.mapper.TbDicMapper
===========================================================
第2次注册
java.lang.IllegalArgumentException: Result Maps collection already contains value for com.pf.test.mapper.TbDicMapper.testMethod-Map
at com.baomidou.mybatisplus.core.MybatisConfiguration$StrictMap.put(MybatisConfiguration.java:449)
at com.baomidou.mybatisplus.core.MybatisConfiguration$StrictMap.put(MybatisConfiguration.java:403)
at com.baomidou.mybatisplus.core.MybatisConfiguration.addResultMap(MybatisConfiguration.java:274)
at org.apache.ibatis.builder.MapperBuilderAssistant.addResultMap(MapperBuilderAssistant.java:181)
at com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder.applyResultMap(MybatisMapperAnnotationBuilder.java:233)
at com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder.parseResultMap(MybatisMapperAnnotationBuilder.java:206)
at com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder.parse(MybatisMapperAnnotationBuilder.java:104)
at com.baomidou.mybatisplus.core.MybatisMapperRegistry.addMapper(MybatisMapperRegistry.java:90)
at com.baomidou.mybatisplus.core.MybatisConfiguration.addMapper(MybatisConfiguration.java:129)
at com.aecc.sysmanager.MybatisPlusTest.test(MybatisPlusTest.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:95)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:91)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:60)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)