使用MybatisPlus的lambdaQuery().one()查询时,如果查询结果不存在,那么就会报错:

1
2
3
4
5
6
7
com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Class must not be null  
at com.baomidou.mybatisplus.core.toolkit.ExceptionUtils.mpe(ExceptionUtils.java:49) ~[mybatis-plus-core-3.5.3.jar:3.5.3]
at com.baomidou.mybatisplus.core.toolkit.Assert.isTrue(Assert.java:38) ~[mybatis-plus-core-3.5.3.jar:3.5.3]
at com.baomidou.mybatisplus.core.toolkit.Assert.notNull(Assert.java:72) ~[mybatis-plus-core-3.5.3.jar:3.5.3]
at com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils.currentSessionFactory(GlobalConfigUtils.java:53) ~[mybatis-plus-core-3.5.3.jar:3.5.3]
at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.sqlSession(SqlHelper.java:86) ~[mybatis-plus-extension-3.5.3.jar:3.5.3]
at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.execute(SqlHelper.java:301) ~[mybatis-plus-extension-3.5.3.jar:3.5.3]

解决办法

mybatis-plus-boot-starter版本升级到3.5.3.1

原因

IService接口的lambdaQuery()方法构建一个LambdaQueryChainWrapper类的实现对象并返回用于后面的链式调用,而这里构建LambdaQueryChainWrapper类对象时使用的是LambdaQueryChainWrapper(BaseMapper<T> baseMapper, Class<T> entityClass)这个构造方法,这个方法并没有给当前类的成员变量entityClass赋值:

1
2
3
4
5
public LambdaQueryChainWrapper(BaseMapper<T> baseMapper, Class<T> entityClass) {  
super();
this.baseMapper = baseMapper;
super.wrapperChildren = new LambdaQueryWrapper<>(entityClass);
}

接下来看链式调用的one()方法,这个方法会执行ChainWrapper接口的默认方法execute(SFunction<BaseMapper<T>, R> function),这个方法在执行传入进来的function函数,这个函数就是mapper.selectOne(getWrapper()),当这个函数执行的结果为null时,这里就会执行orElseGet后面的部分:

1
2
3
default <R> R execute(SFunction<BaseMapper<T>, R> function) {  
return Optional.ofNullable(getBaseMapper()).map(function).orElseGet(() -> SqlHelper.execute(getEntityClass(), function));
}

而在后面这个部分中会执行getEntityClass()这个函数,在这里这个函数的实现是由LambdaQueryChainWrapper类来实现的:

1
2
3
4
@Override  
public Class<T> getEntityClass() {
return entityClass;
}

可以看到这个实现就是直接返回了LambdaQueryChainWrapper类的成员变量entityClass,而这个变量在我们前面讲到的构建LambdaQueryChainWrapper类对象过程中是没有赋值的,所以导致后面在使用这个值时报了MybatisPlusException: Class must not be null异常,而在3.5.3.1版本中LambdaQueryChainWrapper类的getEntityClass()函数返回的是super.wrapperChildren.getEntityClass()

1
2
3
4
@Override  
public Class<T> getEntityClass() {
return super.wrapperChildren.getEntityClass();
}