翻车!记一次使用 Lombok 造成的事故

★★★建议星标我们★★★
翻车!记一次使用 Lombok 造成的事故文章插图
翻车!记一次使用 Lombok 造成的事故文章插图
2020年Java原创面试题库连载中
【000期】Java最全面试题库思维导图
【020期】JavaSE系列面试题汇总(共18篇)
【028期】JavaWeb系列面试题汇总(共10篇)
【042期】JavaEE系列面试题汇总(共13篇)
【049期】数据库系列面试题汇总(共6篇)
【053期】中间件系列面试题汇总(共3篇)
【065期】数据结构与算法面试题汇总(共11篇)
【076期】分布式面试题汇总(共10篇)
【077期】综合面试题系列(一)
【078期】综合面试题系列(二)
【079期】综合面试题系列(三)
【080期】综合面试题系列(四)
【081期】综合面试题系列(五)
【082期】综合面试题系列(六)
【083期】综合面试题系列(七)
【084期】综合面试题系列(八)
【085期】综合面试题系列(九)
【086期】综合面试题系列(十)
【087期】综合面试题系列(十一)
【088期】综合面试题系列(十二)
【089期】综合面试题系列(十三)
更多内容 , 点击上面蓝字查看
翻车!记一次使用 Lombok 造成的事故文章插图
作者:liuxuzxx
序言去年在项目当中引入了Lombok插件 , 着实解放了双手 , 代替了一些重复的简单工作(Getter,Setter,toString等方法的编写) 。
但是 , 在使用的过程当中 , 也发现了一些坑 , 开始的时候并没有察觉到是Lombok的问题 , 后来跟踪了对应的其他组件的源码 , 才发现是Lombok的问题!
Setter-Getter方法的坑问题发现我们在项目当中主要使用Lombok的Setter-Getter方法的注解 , 也就是组合注解@Data , 但是在一次使用Mybatis插入数据的过程当中 , 出现了一个问题 , 问题描述如下:
我们有个实体类:
@Data
public class NMetaVerify{
private NMetaType nMetaType;
private Long id;
....其他属性
}
当我们使用Mybatis插入数据的时候 , 发现 , 其他属性都能正常的插入 , 但是就是nMetaType属性在数据库一直是.
解决当我debug项目代码到调用Mybatis的插入SQL对应的方法的时候 , 我看到NMetaVerify对象的nMetaType属性还是有数据的 , 但是执行插入之后 , 数据库的nMetaType字段就是一直是 , 原先我以为是我的枚举类型写法不正确 , 看了下别的同样具有枚举类型的字段 , 也是正常能插入到数据库当中的 , 这更让我感觉到疑惑了.
于是 , 我就跟踪Mybatis的源码 , 发现Mybatis在获取这个nMetaType属性的时候使用了反射 , 使用的是getxxxx方法来获取的 , 但是我发现nMetaType的get方法好像有点和Mybatis需要的getxxxx方法长的好像不一样.问题找到了!
原因Lombok对于第一个字母小写 , 第二个字母大写的属性生成的get-set方法和Mybatis以及idea或者说是Java官方认可的get-set方法生成的不一样:
Lombok生成的Get-Set方法
@Data
public class NMetaVerify {
private Long id;
private NMetaType nMetaType;
private Date createTime;
public void lombokFound{
NMetaVerify nMetaVerify = new NMetaVerify;
nMetaVerify.setNMetaType(NMetaType.TWO); //注意:nMetaType的set方法为setNMetaType , 第一个n字母大写了 ,
nMetaVerify.getNMetaType; //getxxxx方法也是大写
}
}
idea , Mybatis , Java官方默认的行为为:
public class NMetaVerify {
private Long id;
private NMetaType nMetaType;
private Date createTime;
public Long getId {
return id;
}
public void setId(Long id) {
this.id = id;
}
public NMetaType getnMetaType {//注意:nMetaType属性的第一个字母小写
return nMetaType;
}
public void setnMetaType(NMetaType nMetaType) {//注意:nMetaType属性的第一个字母小写
this.nMetaType = nMetaType;
}
public Date getCreateTime {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}
Mybatis(3.4.6版本)解析get-set方法获取属性名字的源码:
package org.apache.ibatis.reflection.property;
import java.util.Locale;
import org.apache.ibatis.reflection.ReflectionException;
/**
* @author Clinton Begin
*/
public final class PropertyNamer {
private PropertyNamer {
// Prevent Instantiation of Static Class
}
public static String methodToProperty(String name) {
if (name.startsWith("is")) {//is开头的一般是bool类型 , 直接从第二个(索引)开始截取(简单粗暴)