使用MybatisPlus的lambdaQuery().one()
查询时,如果查询结果不存在,那么就会报错:
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
赋值:
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
后面的部分:
default <R> R execute(SFunction<BaseMapper<T>, R> function) {
return Optional.ofNullable(getBaseMapper()).map(function).orElseGet(() -> SqlHelper.execute(getEntityClass(), function));
}
而在后面这个部分中会执行getEntityClass()
这个函数,在这里这个函数的实现是由LambdaQueryChainWrapper
类来实现的:
@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()
:
@Override
public Class<T> getEntityClass() {
return super.wrapperChildren.getEntityClass();
}
网友评论