• MybatisPlusException: can not find lambda cache for this entity[]异常解决


    文章目录

    场景说明

      简单来说,我们系统中许多数据都是树状结构的,所以我定义了一个实体类父类BaseTreePO,并且想封装一个通用的树状对象的Service类,部分代码如下:

    public interface TreeService<T extends BaseTreePO> extends IService<T> {
    
        default String getCurrentMaximumChildPath(T entity, String parentPath) {
            LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<T>()
                    .orderByDesc(T::getPath);//在这里通过T::getPath获取字段名时报错
    
            if (StrUtil.isEmpty(parentPath)) {
                wrapper.isNull(T::getParentPath);
            } else {
                wrapper.eq(T::getParentPath, parentPath);
            }
    
            T maxPathChild = this.getBaseMapper().selectOne(this.doAppend(wrapper, entity));
            return ObjectUtil.isEmpty(maxPathChild) ? null : maxPathChild.getPath();
        }
    }
    


      如上述代码所示,在执行T::getPath时报错,报错堆栈信息如下:

    com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: can not find lambda cache for this entity [com.copm.ifm.base.basic.pojo.BaseTreePO]
    	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.conditions.AbstractLambdaWrapper.tryInitCache(AbstractLambdaWrapper.java:94)
    	at com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper.getColumn(AbstractLambdaWrapper.java:79)
    	at com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper.columnToString(AbstractLambdaWrapper.java:62)
    	at com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper.columnToString(AbstractLambdaWrapper.java:58)
    	at com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper.columnToString(AbstractLambdaWrapper.java:38)
    	at com.baomidou.mybatisplus.core.conditions.AbstractWrapper.lambda$orderBy$82c52469$1(AbstractWrapper.java:310)
    	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
    	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    	at com.baomidou.mybatisplus.core.conditions.segments.OrderBySegmentList.transformList(OrderBySegmentList.java:37)
    	at com.baomidou.mybatisplus.core.conditions.segments.AbstractISegmentList.addAll(AbstractISegmentList.java:60)
    	at com.baomidou.mybatisplus.core.conditions.segments.MergeSegments.add(MergeSegments.java:50)
    	at com.baomidou.mybatisplus.core.conditions.AbstractWrapper.doIt(AbstractWrapper.java:469)
    	at com.baomidou.mybatisplus.core.conditions.AbstractWrapper.orderBy(AbstractWrapper.java:310)
    	at com.baomidou.mybatisplus.core.conditions.AbstractWrapper.orderBy(AbstractWrapper.java:47)
    	at com.baomidou.mybatisplus.core.conditions.interfaces.Func.orderByDesc(Func.java:264)
    	at com.baomidou.mybatisplus.core.conditions.interfaces.Func.orderByDesc(Func.java:245)
    	at com.copm.ifm.base.service.TreeService.getCurrentMaximumChildPath(TreeService.java:161)
    

    解决方案

      给对应的父类也单独增加一个Mapper类即可:

    package com.copm.ifm.base.service.base.mapper;
    
    import com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder;
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.copm.ifm.base.basic.pojo.BaseTreePO;
    
    /**
     * 因为MP3.2+之后不会缓存实体类的父类字段信息,所以在使用泛型的Lambda表达式时会报错
     * {@code MybatisPlusException: can not find lambda cache for this entity [com.copm.ifm.base.basic.pojo.BaseTreePO]}
     * 原因是在执行{@link com.baomidou.mybatisplus.core.toolkit.LambdaUtils#getColumnMap(Class)}时
     * {@code COLUMN_CACHE_MAP}中没有{@link BaseTreePO}的信息
     *
     * <p>
     * 根据源码
     * {@link com.baomidou.mybatisplus.core.MybatisMapperRegistry#addMapper(Class)}
     * {@link MybatisMapperAnnotationBuilder#parse()}方法的加载逻辑
     * <p>
     * 他会将所有扫描到的mapper中的泛型({@link BaseMapper<Class>}中的Class,即实体类)的字段信息缓存到
     * {@link com.baomidou.mybatisplus.core.toolkit.LambdaUtils}中的{@code COLUMN_CACHE_MAP}中。
     * 但是MP3.2+之后不会加载父类的信息,所以{@code COLUMN_CACHE_MAP}中没有相关缓存,就报错了。
     * <p>
     * 因此我们单独为{@link BaseTreePO}添加一个的Mapper类,这样他就会缓存该类的信息了。
     */
    public interface BaseTreeMapper extends BaseMapper<BaseTreePO> {
    
    }
    
    

      具体原因也写在了代码的注释上,这样别人在看到这个类的时候也知道是怎么回事了。

      需要注意的是,我这里是没有加@Mapper注解的,因为我在启动类上加了@MapperScan注解。加了@MapperScan就不需要给每个Mapper类单独加@Mapper了,如果你没有加@MapperScan,则需要给他加上@Mapper

  • 相关阅读:
    css | js 实现扩展卡片小demo
    ESLint如何配置
    (js描述的)数据结构[哈希表1.3](10)
    (js描述的)数据结构[哈希表1.2](9)
    VSCode——自定义VSCode背景图片
    VSCode 初次写vue项目并一键生成.vue模版
    (js描述的)数据结构[哈希表1.1](8)
    (js描述的)数据结构[字典](7)
    Vue 实战项目: 硅谷外卖(1)
    脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?
  • 原文地址:https://www.cnblogs.com/exmyth/p/14342611.html
Copyright © 2020-2023  润新知