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

Jacky Java 2023-01-07 53

###场景说明 简单来说,我们系统中许多数据都是需要做逻辑删除的,所以我定义了一个实体类父类BaseEntity,并且想封装一个通用的逻辑删除的Service类,部分代码如下

public interface DelEntityService<Entity extends BaseEntity> extends IService<Entity> {
    default boolean delEntity(Entity entity) {
        LambdaUpdateWrapper<Entity> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Entity::getDel, 1).eq(Entity::getId, entity.getId());
        return update(wrapper);
    }
}

在执行Entity::getDel,提示异常信息

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<Entity> wrapper = new LambdaQueryWrapper<Entity>()
                .setEntityClass((Class<Entity>) entity.getClass());//指定实体类类型

        //或
        LambdaQueryWrapper<Entity> wrapper = new LambdaQueryWrapper<>((Class<Entity>)entity.getClass());

        //或
        //这种慎用!!!因为该wrapper的条件中会加入entity中有值的属性值
        //即如果entity.getId() = 1,则wrapper的条件中就会增加 and id = 1的条件。
        LambdaQueryWrapper<Entity> wrapper = new LambdaQueryWrapper<>(entity);

这种方法有一个致命的确缺点就是要传入泛型Entity的对象entity,本身这么做的原因就是不想传入entity,所有这种方式在某些情况下不可用。

第二种:给对应的父类BaseEntity也单独增加一个Mapper类
@Mapper
public interface BaseEntityMapper extends BaseMapper<BaseEntity> {

}