调用Mybatis plus中的saveBatch方法报找不到表的问题

1.问题现象

在用Mybatis plus开发的项目中,用自带的API批量保存的方法saveBatch操作时,发现报没有找到表的错误。

错误日志截图如下:

表实际是存在的,且发现其他的方法都没有问题,包括save、update等单个的方法,都是正常的。百思不得其解,配置和代码都没有问题。

下面是该数据源对应的配置文件。

dataSourceConfig中配置的mapperLocations的位置:

其apollo中配置的value值为:classpath*:/mapper/*.xml

原来的maper.xml路径:

2.问题分析

在项目中用了2个数据源,上面是其中的一个数据源。

另一个数据源的mapper.xml配置的路径是:

其apollo中配置的value值也为:classpath*:/mapper/*.xml

本来是想保存数据到A数据库,结果是执行的是另一个数据库B,其实是因为 SqlSessionFactory 错误导致的。

项目中有2个数据源,分别用的不同的 SqlSessionFactory。

经分析跟踪代码后发现执行saveBatch后最终调用到了这个方法:

java 复制代码
 public static boolean executeBatch(Class<?> entityClass, Log log, Consumer<SqlSession> consumer) {
        SqlSessionFactory sqlSessionFactory = sqlSessionFactory(entityClass);
        SqlSessionHolder sqlSessionHolder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sqlSessionFactory);
        boolean transaction = TransactionSynchronizationManager.isSynchronizationActive();
        if (sqlSessionHolder != null) {
            SqlSession sqlSession = sqlSessionHolder.getSqlSession();
            //原生无法支持执行器切换,当存在批量操作时,会嵌套两个session的,优先commit上一个session
            //按道理来说,这里的值应该一直为false。
            sqlSession.commit(!transaction);
        }
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
        if (!transaction) {
            log.warn("SqlSession [" + sqlSession + "] was not registered for synchronization because DataSource is not transactional");
        }

com.baomidou.mybatisplus.core.metadata.TableInfoHelper 中 initTableInfo方法会将每个实体类与对应的数据库配置保存到缓存:TABLE_INFO_CACHE

也就是,我们在创建 SqlSessionFactory 时候设置的 setMapperLocations, 设置路径下的所有mapper.xml 对应的实体都会保存对应的数据库配置。

因此,我们需要将不同的 SqlSessionFactory 配置,用不同的 mapper 目录来扫描。不同数据源的操作,放在各自的 mapper 子目录下,作区分。

上面我们定义2个SqlSessionFactory中配置的mapper文件路径是一样的。

由于 classpath*:mapper/**/*Mapper.xml 路径一样,导致初始化实体类和数据库配置对应关系,被覆盖的现象。

即同样的 mapper.xml 文件中被不同的 SqlSessionFactory 扫描了两次,导致mapper.xml中的实体类信息只有一种SqlSessionFactory信息。

3.解决办法

需要将其中的一个数据源对应的mapper文件映射的路径改一下,改成和另一个数据源配置的路径不同,就可以了。

修改后的路径:

相关推荐
冼紫菜2 分钟前
[特殊字符]CentOS 7.6 安装 JDK 11(适配国内服务器环境)
java·linux·服务器·后端·centos
isyangli_blog17 分钟前
(1-4)Java Object类、Final、注解、设计模式、抽象类、接口、内部类
java·开发语言
三块钱079424 分钟前
【原创】基于视觉大模型gemma-3-4b实现短视频自动识别内容并生成解说文案
开发语言·python·音视频
易只轻松熊25 分钟前
C++(20): 文件输入输出库 —— <fstream>
开发语言·c++·算法
芯眼28 分钟前
ALIENTEK精英STM32F103开发板 实验0测试程序详解
开发语言·c++·stm32·单片机·嵌入式硬件·社交电子
青出于兰1 小时前
C语言| 指针变量的定义
c语言·开发语言
玉笥寻珍1 小时前
筑牢信息安全防线:涉密计算机与互联网隔离的理论实践与风险防控
开发语言·计算机网络·安全·计算机外设·php·安全架构·安全性测试
蓝莓味柯基1 小时前
Lodash isEqual 方法源码实现分析
开发语言
秋野酱1 小时前
Spring Boot 项目的计算机专业论文参考文献
java·spring boot·后端
秋野酱2 小时前
python项目参考文献
开发语言·python