版权说明: 本文由博主keep丶原创,转载请注明出处。
原文地址: https://blog.csdn.net/qq_38688267/article/details/112621293
开发环境: MyBatis-Plus3.4.1

文章目录

  • 场景说明
  • 解决方案

场景说明

  简单来说,我们系统中许多数据都是树状结构的,所以我定义了一个实体类父类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)

解决方案

  • 第一种: 给对应的Wrapper指定对象类型,使用AbstractWrapper#setEntityClass(Class)方法:
        LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<T>().setEntityClass((Class<T>) entity.getClass())//指定实体类类型.orderByDesc(T::getPath);//或LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>((Class<T>)entity.getClass());//或//这种慎用!!!因为该wrapper的条件中会加入entity中有值的属性值//即如果entity.getId() = 1,则wrapper的条件中就会增加 and id = 1的条件。LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>(entity);

这种方案需要每个相关Wrapper都指定,如果要一劳永逸的方式请使用第二种:

  • 第二种:给对应的父类也单独增加一个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;/*** 在使用存在父类的泛型的Lambda表达式时会报错:* {@code MybatisPlusException: can not find lambda cache for this entity [com.copm.ifm.base.basic.pojo.BaseTreePO]}* <p>* 原因是在执行{@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 com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder#parse()}* {@link com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder#parsePendingMethods()}* {@link com.baomidou.mybatisplus.core.injector.AbstractSqlInjector#inspectInject(MapperBuilderAssistant, Class)}* {@link com.baomidou.mybatisplus.core.metadata.TableInfoHelper#initTableInfo(Configuration, String, Class)}* {@link com.baomidou.mybatisplus.core.toolkit.LambdaUtils#installCache(TableInfo)}* 方法的加载逻辑* <p>* 他会将所有扫描到的mapper中的泛型({@link BaseMapper<Class>}中的Class,即实体类)的字段信息缓存到* {@link com.baomidou.mybatisplus.core.toolkit.LambdaUtils}中的{@code COLUMN_CACHE_MAP}中。* 但是没有单独缓存父类的信息,所以{@code COLUMN_CACHE_MAP}中没有相关缓存,就报错了。* <p>* 因此我们单独为{@link BaseTreePO}添加一个的Mapper类,这样他就会缓存该类的信息了。* <p>* 另外一个解决方案是给相关Wrapper指定泛型类型,告诉mp让他加载子类的字段信息,也可以解决该问题:* 使用{@link com.baomidou.mybatisplus.core.conditions.AbstractWrapper#setEntityClass(Class)}**/
public interface BaseTreeMapper extends BaseMapper<BaseTreePO> {
}

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

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

MybatisPlusException: can not find lambda cache for this entity[]异常解决相关推荐

  1. MybatisPlus报错can not find lambda cache for this entity

    BaseMapper的<你自己的实体类对象>,因为我是多表查询使用了vo,但是泛型还是Entiy而不是自己的vo类,才导致这个报错 问题代码 @Repository public inte ...

  2. can not find lambda cache for this property [XXX] of entity [com.XXX.XXX]

    我们在使用mybatisplus 时使用Lambda 表达式做查询条件会遇到mybatis拿不到缓存问题: 错误1:com.baomidou.mybatisplus.core.exceptions.M ...

  3. oracle library cache lock,【案例】Oracle等待事件library cache lock产生原因和解决办法...

    [案例]Oracle等待事件library cache lock产生原因和解决办法 时间:2016-12-07 18:56   来源:Oracle研究中心   作者:网络   点击: 次 天萃荷净 O ...

  4. Java Lambda表达式forEach无法跳出循环的解决思路

    Java Lambda表达式forEach无法跳出循环的解决思路 如果你使用过forEach方法来遍历集合,你会发现在lambda表达式中的return并不会终止循环,这是由于lambda的底层实现导 ...

  5. Linux中buff/cache内存占用过高解决办法

    Linux中buff/cache内存占用过高解决办法 在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个centos7的系统上,free命令的显示内容大概是这样一个状态: 这个 ...

  6. oracle library cache lock,【DB】彻底搞清楚library cache lock的成因和解决方法(一)

    问题描述: 接到应用人员的报告,说是在任何对表CSNOZ629926699966的操作都会hang,包括desc CSNOZ629926699966,例如: > sqlplus SQL*Plus ...

  7. Linux中Cache内存占用过高解决办法

    在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个RHEL6的系统上,free命令的显示内容大概是这样一个状态: 这里的默认显示单位是kb,我的服务器是128G内存,所以数字显 ...

  8. Spring Cache使用Redisson分布式锁解决缓存击穿问题

    文章目录 1 什么是缓存击穿 2 为什么要使用分布式锁 3 什么是Redisson 4 Spring Boot集成Redisson 4.1 添加maven依赖 4.2 配置yml 4.3 配置Redi ...

  9. WP Super Cache与WPtouch冲突的解决办法

    WP Super Cach是一款贼牛逼的wordpress缓存插件,WPtouch是一个据说很好用的手机界面插件.今天试了试,发现有冲突,下面是解决方法: 1.在WP Super Cache设置高级选 ...

最新文章

  1. 为什么 ConcurrentHashMap 的读操作不需要加锁?
  2. 探索JAVA并发 - 悲观锁和乐观锁
  3. lambda表达式浅析【C++学习笔记】
  4. UVM序列篇之一:新手上路
  5. mysql 主从 仅备份从库_MySQL主从复制 - 从数据库备份数据库
  6. 【Java】Java Object对象
  7. 杨强教授领衔力作,《迁移学习》最新出炉,解决AI“最后一公里”问题 | 赠书...
  8. Codeforces - 570D 离散DFS序 特殊的子树统计 (暴力出奇迹)
  9. 八位抢答器【51单片机】
  10. dp线长什么样子_一根DP线引发的显示器超频事件
  11. spline: 计算机曲线简史(转载)
  12. Flink重启策略Restart-Strategy
  13. [JZOJ4567]nekopara
  14. html实现从内向外渐变色,CSS3 由内到外(放射性)渐变
  15. 【信号与系统】Multisim 仿真连续时间系统的时域分析
  16. Java与.net的选择和比较
  17. 软考-法律法规和标准化
  18. XXL-Job分布式任务调度框架-- 介绍和调度中心的搭建启动1
  19. IMS 呼叫流程简单分析
  20. 即时通讯整体解决方案

热门文章

  1. 旅游地理学期末(大学)
  2. 阿里云CentOS7挂载SSD云盘的方法
  3. 漫反射与高光反射总结
  4. SQL注入—跨库注入
  5. NovAtel 卫星接收机 718D 数据手册简介
  6. 这些片子你猜到结局了吗?
  7. pychar调试报错:Cython extension speeds up Python debugging
  8. C/C++中substr函数的应用(简单讲解)
  9. idm下载器如何使用 idm下载器使用技巧
  10. 理解GloVe模型(+总结)