黑马点评P51实现秒杀下单的时候其中有一步需要使用mp更新数据库
原代码
下面是老师视频中的代码 项目可以正常运行
boolean success = seckillVoucherService.update()
.setSql("stock = stock - 1")
.eq("voucher_id", voucherId)
.update();
使用lambda的代码
刚好本人前2天才学的mp 便想着使用另外一种方式来更新数据库(上面的字段是写死的,想要通过反射来获取字段)
这是我写的代码
boolean success = seckillVoucherService.lambdaUpdate()
.set(SeckillVoucher::getStock, stock - 1)
.eq(SeckillVoucher::getVoucherId, voucherId)
.update();
然后运行程序的时候意外的发现代码在.set这行就报错了
报错信息
java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.lang.Class java.lang.invoke.SerializedLambda.capturingClass accessible: module java.base does not "opens java.lang.invoke" to unnamed module @41e36e46
解决方法
将项目mp原本的3.4.3版本替换为3.5.3
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
替换完成后即可正常运行
具体问题产生原因(github上找的)
该问题应当是由于JDK16引入的 JEP 396 特性造成。其实JDK9开始就已经引入了宽松强封装,但是JDK16进一步提高了JDK的安全性,默认情况下强封装JDK内部使其无法被非法访问(深度反射)。该特性已造成大量框架的现有代码无法正常运行。
3.4.3修改了识别Lambda的机制,见 #3517 。使用了反射,因而触发 JEP 396 的限制。
目前可以通过 JVM启动参数 --illegal-access=permit
以解除限制。见 JEP 396
或者使用 --add-opens java.base/java.lang.invoke=ALL-UNNAMED
。见 --add-opens