MetaObjectHandler自动填充不生效

背景:

导入时涉及到保存数据到数据库,插入失败,错误如下

解决方案:

插入的实体类基本都继承了一个BaseEntity,会涉及到tmSmp和tmCreate这两个自动填充字段,tmSmp是FieldFill.INSERT类型,tmCreate是FieldFill.INSERT_UPDATE

自动填充一般流程:自行实现MetaObjectHandler并注入到IOC容器中即可

分析源码MybatisPlusAutoConfiguration#sqlSessionFactory可知

复制代码
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    // TODO 使用 MybatisSqlSessionFactoryBean 而不是 SqlSessionFactoryBean
    MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
    factory.setDataSource(dataSource);
    ......
    // TODO 此处必为非 NULL
    GlobalConfig globalConfig = this.properties.getGlobalConfig();
    // TODO 注入填充器
    this.getBeanThen(MetaObjectHandler.class, globalConfig::setMetaObjectHandler);
    // TODO 注入主键生成器
    this.getBeanThen(IKeyGenerator.class, i -> globalConfig.getDbConfig().setKeyGenerator(i));
    // TODO 注入sql注入器
    this.getBeanThen(ISqlInjector.class, globalConfig::setSqlInjector);
    // TODO 注入ID生成器
    this.getBeanThen(IdentifierGenerator.class, globalConfig::setIdentifierGenerator);
    // TODO 设置 GlobalConfig 到 MybatisSqlSessionFactoryBean
    factory.setGlobalConfig(globalConfig);
    return factory.getObject();
}
复制代码

 

IOC容器在没有SqlSessionFactory这个bean对象时会去调用这个方法创建一个,并且注入填充器

但是由于本次的项目是多数据源,需要自行写SqlSessionFactory的返回,所以我们需要自行去注入填充器

 

// 设置自动填充
GlobalConfig globalConfig = this.mybatisPlusProperties.getGlobalConfig();
if (globalConfig == null) {
    globalConfig = GlobalConfigUtils.defaults();
}
globalConfig.setMetaObjectHandler(metaObjectHandler);
factory.setGlobalConfig(globalConfig);

一般流程到这里就OK了,但是每次我debug的时候都取不到MetaObjectHandler,MybatisParameterHandler#insertFill中的GlobalConfigUtils.getMetaObjectHandler(this.configuration)始终为空

最后将我的Mybatis配置类实现了SmartInitializingSingleton,在所有单例实例化结束后去重新设置一下填充器

@Override
public void afterSingletonsInstantiated() {
GlobalConfig globalConfig1 = GlobalConfigUtils.getGlobalConfig(originConfiguration2);
if (globalConfig1 != null) {
globalConfig1.setMetaObjectHandler(metaObjectHandler);
}
}

完美解决问题,最终找到罪魁祸首

在我定义SqlSessionFactory时有一段代码如下

MybatisConfiguration originConfiguration = this.mybatisPlusProperties.getConfiguration();
        MybatisConfiguration configuration = new MybatisConfiguration();
        if (originConfiguration != null) {
            BeanUtils.copyProperties(originConfiguration, configuration);
        }

这个工具类copy的时候会调用到两个弃用的方法,会调用MybatisConfiguration两个弃用的方法getGlobalConfig和setGlobalConfig

因此需要将copy的代码改成

BeanUtils.copyProperties(originConfiguration, configuration, "globalConfig");

即可

最后望大家写代码细心,少出bug(#^.^#)

posted @   lhbili  阅读(1128)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示