前言

报错堆栈信息如下,基本是mybatis-plus源码中的一些东西:

com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: java.lang.Object Not Found TableInfoCache.
	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.core.toolkit.GlobalConfigUtils.currentSessionFactory(GlobalConfigUtils.java:54)
	at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.sqlSessionFactory(SqlHelper.java:71)
	at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.executeBatch(SqlHelper.java:161)
	at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.executeBatch(SqlHelper.java:207)
	at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.executeBatch(ServiceImpl.java:239)
	at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.saveBatch(ServiceImpl.java:135)
	at com.baomidou.mybatisplus.extension.service.IService.saveBatch(IService.java:73)

我这里的问题主要是,调用单个插入数据,是能插入成功的。调用批量时就会报错。

网上有些朋友说是因为实体定义,表名之类的问题。这个肯定不是我当前遇到的,否则单个插入数据也会报错。而且报错信息也会有所不同。

问题回溯

报错的地方是全局配置类中获取表信息的时候,取了个空:
在这里插入图片描述
可以看到此处的问题,传进来的clazz 居然成了 Object类型的。这就是问题的根本原因,压根没有一个表能对应上Object。

那么这个Object 是从哪来的呢?

排查过程

从堆栈信息入手,向前找,看看这个clazz 是谁传过来的。
终于,在源码中找到了。在mybatis-plus的service实现类中

com.baomidou.mybatisplus.extension.service.impl.ServiceImpl

批量方法:
在这里插入图片描述
再继续查找,这是当前实现类的属性值,应该是在对象初始化时,就赋值了。
在这里插入图片描述
这里是获取了父类的范型类型,看到这里,大概知道这个错误的原因了。就是这个类型,获取到的是Object类型,导致了后来的错误。

    public static Class<?> getSuperClassGenericType(final Class<?> clazz, final int index) {
        Type genType = clazz.getGenericSuperclass();
        if (!(genType instanceof ParameterizedType)) {
            logger.warn(String.format("Warn: %s's superclass not ParameterizedType", clazz.getSimpleName()));
            return Object.class;
        }
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        if (index >= params.length || index < 0) {
            logger.warn(String.format("Warn: Index: %s, Size of %s's Parameterized Type: %s .", index,
                    clazz.getSimpleName(), params.length));
            return Object.class;
        }
        if (!(params[index] instanceof Class)) {
            logger.warn(String.format("Warn: %s not set the actual class on superclass generic parameter",
                    clazz.getSimpleName()));
            return Object.class;
        }
        return (Class<?>) params[index];
    }

一般来说,我们在写业务层时,会这样写:

public class UserService extends ServiceImpl<UserMapper, User> {
...
}

然后使用这个UserService就没有这个问题。
但是我现在这个会出这个问题,是因为在继承关系中,多加了一层

我目前使用的类,可以说是又继承了 UserService,最关键的是UserService 并没有范型类型。因此直接返回了Object.class类型。

总结

在增加了继承关系的写法中,无法使用serviceImpl的一些方法。但是调用mapper的方法,是可以的。
在这里插入图片描述

这也就是为什么我的批量操作报错,单个插入却是可以成功的原因。

然后就是写这个层级结构时,可以将数据库相关的内容,全部写在 ServiceImpl 的直接子类中。其他地方再去调用。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐