当前使用版本

com.baomidou mybatis-plus-boot-starter 3.1.2

该问题是怎么引起的?

我继承了ServiceImpl,写了个子类作为基类 public class RestPatchServiceImpl< T > extends ServiceImpl<BaseMapper< T >, T> 然后使用 public MyService extends RestPatchServiceImpl< Role > 由于ServiceImpl在RestPatchServiceImpl里面拿到的泛型是T,而不是真实的Role, 所以导致ServiceImpl拿不到T的真实类型,当我使用saveBatch的时候就报错了

重现步骤

  1. 写个基类 public class RestPatchServiceImpl< T > extends ServiceImpl<BaseMapper< T >, T>

2.继承基类 @Service public MyService extends RestPatchServiceImpl< Role >

3.调用saveBatch方法 myService.saveBatch(roleList);

4.报错了

报错信息

com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Error: Cannot execute table Method, ClassGenricType not found . at com.baomidou.mybatisplus.core.toolkit.ExceptionUtils.mpe(ExceptionUtils.java:49) at com.baomidou.mybatisplus.core.toolkit.Assert.isTrue(Assert.java:38) at com.baomidou.mybatisplus.core.toolkit.Assert.notNull(Assert.java:72) at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.table(SqlHelper.java:86) at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.sqlStatement(ServiceImpl.java:99) at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.saveBatch(ServiceImpl.java:117) at com.baomidou.mybatisplus.extension.service.IService.saveBatch(IService.java:58) at com.baomidou.mybatisplus.extension.service.IService$$FastClassBySpringCGLIB$$f8525d18.invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:750) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:345) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)

Comment From: miemieYaho

是你使用不当,自己看ServiceImpl里反射获取泛型的代码

Comment From: yolinfeng

是你使用不当,自己看ServiceImpl里反射获取泛型的代码 @miemieYaho

额,要不是我知道这个问题出在哪里,我可能就相信你了 这就是个BUG,我已经找到原因并且修复了 问题出在ServiceImpl的currentModelClass()里 == protected Class currentModelClass() { return (Class) ReflectionKit.getSuperClassGenericType(getClass(), 1); }

这段代码想要从父类里获取第二个泛型的类,但这是不正确的,因为它假设了父类是ServiceImpl,所以获取第二个泛型就拿到了entity的类 问题是这个假设是不成立的,因为我可能有多个继承,比如 public class RestPatchServiceImpl< T > extends ServiceImpl<BaseMapper< T >, T> public MyService extends RestPatchServiceImpl< Role > 这时候的currentModelClass()就报错了,因为getClass()拿到的是MyService ,spuerClass是RestPatchServiceImpl而不是ServiceImpl,所以你上面的假设不成立,所以ReflectionKit.getSuperClassGenericType(getClass(), 1)就拿不到Role而是报错了,因为RestPatchServiceImpl只有一个泛型 ======= 所以这就是个BUG。。。我已经在自己的类里修复了这个问题

Comment From: miemieYaho

我说的就是这,是你使用不当,是让你们直接继承的,而不是叠罗汉

Comment From: yolinfeng

我说的就是这,是你使用不当,是让你们直接继承的,而不是叠罗汉 @miemieYaho

所以还是有问题啊,问题是我确实就是需要叠罗汉啊。。。 这不能一刀切的,我有一些重复的代码,肯定是弄个基类出来继承啊,但总不能让我重复copy到每个service里吧?

Comment From: wuwu955

请问这个问题 是修改了代码逻辑 还是说规范使用?