mybtais-plus报错BuilderException: Error evaluating expression 'ew.sqlSegment != null and ew.sqlSegment != '' and ew.nonEmptyOfNormal' Cause: org.apache.ibatis.ognl.OgnlException: sqlSegment

在学习项目时,出现了这个报错,
mybtais-plus报错BuilderException: Error evaluating expression 'ew.sqlSegment != null and ew.sqlSegment != '' and ew.nonEmptyOfNormal' Cause: org.apache.ibatis.ognl.OgnlException: sqlSegment[com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: This is impossible to happen]
仔细这个错误内容是,错误的表达式(Error evaluating expression )造成了(Cause:)一个Ognl异常(OgnlException)异常内容是sql片段(sqlSegment)
根据异常信息,定位到Service层的这个方法,使用了LambdaQuery方法,导致错误,代码如下:

@Override
public User login(LoginFormDTO loginDTO) {
  ...
  User user = lambdaQuery().eq(User::getUsername, username).one();
  ...
}

错误原因应该是通过lambda生成的Ognl表达式(Ojnl是java中一个开源的表达式语言)存在sql片段异常。
这条代码功能都是框架(lombok框架和mybatisplus框架)实现的,我想着框架在功能上应该不会有问题,所以应该是框架的版本冲突导致的,

在飞书看到了有大佬找到了问题所在,好像是MyBatisPlus和jdk版本不适配的问题,3.4.3版本的MyBatis Plus的jdk要16以下,jdk从16开始会限制外部类对jdk内部类的反射调用。
而MyBatisPlus-3.4.3中LambdaQuery获取字段的方法,是用getter的方法,通过反射获取方法的LambdaMeta,再通过方法名获取字段。
过程中会com.baomidou.mybatisplus.core.toolkit.support.SerializedLambdaMeta类会保存一个类型为java.lang.invoke.SerializedLambda的属性,这里会触发高版本JDK报异常。
解决方法:把jdk版本改成11,或者升级MyBatisPlus-3.4.3到3.5.6

// LambdaQuery通过getter获取字段的方法
protected ColumnCache getColumnCache(SFunction<T, ?> column){
 LambdaMeta meta = LambdaUtils.extract(column);
 String fieldName = PropertyNamer.methodToProperty(meta.getImplMethodName());
 ...
}


 public static <T> LambdaMeta extract(SFunction<T, ?> func) {
      // 1. IDEA 调试模式下 lambda 表达式是一个代理
      if (func instanceof Proxy) {
          return new IdeaProxyLambdaMeta((Proxy) func);
      }
      // 2. 反射读取
      try {
          Method method = func.getClass().getDeclaredMethod("writeReplace");
          return new ReflectLambdaMeta((SerializedLambda) ReflectionKit.setAccessible(method).invoke(func));
      } catch (Throwable e) {
          // 3. 反射失败使用序列化的方式读取
          return new ShadowLambdaMeta(com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda.extract(func));
      }
  }
posted @ 2024-11-01 02:20  白马青衫少年郎  阅读(1711)  评论(0)    收藏  举报