Get to know the pitfalls of Lombok
java Basic Tutorial column introduces you to the pitfalls of Lombok, which is easy to use.
Preface
The Lombok plug-in was introduced into the project last year, which really freed up your hands and replaced some repetitive simple tasks (Getter, Setter, toString, etc. Method writing), however, during the use process, some pitfalls were also discovered. At first, I did not realize that it was a Lombok problem. Later, I tracked the source code of the corresponding other components and found out that it was a Lombok problem!
The pitfalls of the Setter-Getter method
Problem discovery
We mainly use the annotations of Lombok's Setter-Getter method in the project, which is the combined annotation @Data, but in the project During a process of inserting data using Mybatis, a problem occurred. The problem is described as follows:
我们有个实体类: @Data public class NMetaVerify{ private NMetaType nMetaType; private Long id; ....其他属性 }复制代码
When we used Mybatis to insert data, we found that other attributes could be inserted normally, but the nMetaType attribute was in the database. Has always been null.
Solution
When I debug the project code to call the method corresponding to inserting SQL in Mybatis, I see that the nMetaType attribute of the NMetaVerify object still has data, but after executing the insertion, the database The nMetaType field is always null. I originally thought that my enumeration type was written incorrectly. After looking at other fields that also have enumeration types, they can be inserted into the database normally, which makes me even more confused. . So, I traced the source code of Mybatis and found that Mybatis used reflection to obtain the nMetaType attribute, using the getxxxx method to obtain it. However, I found that the get method of nMetaType seemed to be a bit different from the getxxxx method required by Mybatis. Same. Problem found!
Reason
The get-set method generated by Lombok for attributes with the first letter in lowercase and the second letter in uppercase is generated by Mybatis and idea or the get-set method officially recognized by Java. The difference:
#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 (version 3.4.6) parses the get-set method to obtain the source code of the attribute name:
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类型,直接从第二个(索引)开始截取(简单粗暴) name = name.substring(2); } else if (name.startsWith("get") || name.startsWith("set")) {//set-get的就从第三个(索引)开始截取 name = name.substring(3); } else { throw new ReflectionException("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'."); } //下面这个判断很重要,可以分成两句话开始解释,解释如下 //第一句话:name.length()==1 // 对于属性只有一个字母的,例如private int x; // 对应的get-set方法是getX();setX(int x); //第二句话:name.length() > 1 && !Character.isUpperCase(name.charAt(1))) // 属性名字长度大于1,并且第二个(代码中的charAt(1),这个1是数组下标)字母是小写的 // 如果第二个char是大写的,那就直接返回name if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) { name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);//让属性名第一个字母小写,然后加上后面的内容 } return name; } public static boolean isProperty(String name) { return name.startsWith("get") || name.startsWith("set") || name.startsWith("is"); } public static boolean isGetter(String name) { return name.startsWith("get") || name.startsWith("is"); } public static boolean isSetter(String name) { return name.startsWith("set"); } }复制代码
Mybatis parses the get-set method to test the attribute name
@Test public void foundPropertyNamer() { String isName = "isName"; String getName = "getName"; String getnMetaType = "getnMetaType"; String getNMetaType = "getNMetaType"; Stream.of(isName,getName,getnMetaType,getNMetaType) .forEach(methodName->System.out.println("方法名字是:"+methodName+" 属性名字:"+ PropertyNamer.methodToProperty(methodName))); } #输出结果如下: 方法名字是:isName 属性名字:name 方法名字是:getName 属性名字:name 方法名字是:getnMetaType 属性名字:nMetaType //这个以及下面的属性第二个字母都是大写,所以直接返回name 方法名字是:getNMetaType 属性名字:NMetaType复制代码
Solution
1.修改属性名字,让第二个字母小写,或者说是规定所有的属性的前两个字母必须小写 2.如果数据库已经设计好,并且前后端接口对接好了,不想修改,那就专门为这种特殊的属性使用idea生成get-set方法复制代码
@Accessor(chain = true) annotation problem
Problem discovery
Export using easyexcel(github.com/alibaba/eas…) When I checked, I found that the previous entity class exports were normal, but now the newly added entity class is not normal. After comparison, it was found that the newly added entity class added the @Accessor(chain = true) annotation. Our main purpose is It is convenient for us to call the set method in a chain:
new UserDto() .setUserName("") .setAge(10) ........ .setBirthday(new Date());复制代码
Reason
The bottom layer of easyexcel uses cglib as the reflection toolkit:
com.alibaba.excel.read.listener.ModelBuildEventListener 类的第130行 BeanMap.create(resultModel).putAll(map); 最底层的是cglib的BeanMap的这个方法调用 abstract public Object put(Object bean, Object key, Object value);复制代码
But cglib uses Java's rt A method of the Introspector class in .jar:
# Introspector.java 第520行 if (int.class.equals(argTypes[0]) && name.startsWith(GET_PREFIX)) { pd = new IndexedPropertyDescriptor(this.beanClass, name.substring(3), null, null, method, null); //下面这行判断,只获取返回值是void类型的setxxxx方法 } else if (void.class.equals(resultType) && name.startsWith(SET_PREFIX)) { // Simple setter pd = new PropertyDescriptor(this.beanClass, name.substring(3), null, method); if (throwsException(method, PropertyVetoException.class)) { pd.setConstrained(true); } }复制代码
Solution
1.去掉Accessor注解 2.要么就等待easyexcel的作者替换掉底层的cglib或者是其他,反正是支持获取返回值不是void的setxxx方法就行复制代码
Related free learning recommendations: java basic tutorial
The above is the detailed content of Get to know the pitfalls of Lombok. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Professional guidance: Expert advice and steps for installing the Lombok plug-in in Eclipse, specific code examples are required Summary: Lombok is a Java library that simplifies the writing of Java code through annotations and provides some powerful tools. This article will introduce readers to the steps of how to install and configure the Lombok plug-in in Eclipse, and provide some specific code examples so that readers can better understand and use the Lombok plug-in. Download the Lombok plug-in first, we need

Quick Start: A simple tutorial for installing the Lombok plug-in in Eclipse, which requires specific code examples. In the process of developing Java projects, Lombok is often used as a practical plug-in. Lombok can help us simplify Java code, reduce the writing of boilerplate code, and improve development efficiency. This article will introduce you to how to install and configure the Lombok plug-in in Eclipse, and provide specific code examples. Step 1: Download the Lombok plug-in First, we need to download the Lombok plug-in from the Lombok official website

LombokLombok can simplify java code in the form of simple annotations, thereby improving developers' development efficiency. It is an excellent Java code library in itself. It uses an opportunistic syntax sugar to simplify Java coding and provides a way to streamline Java code. However, Lombok is not a standard Java library. Java classes that often need to be written during web development require time to add corresponding getter/setter, constructor, equals and other methods. When there are many attributes, there will be a large number of getter/setter methods. These are very lengthy and do not have much technical content. Once the attributes are modified, it is easy to forget to modify the corresponding methods.

Complete Guide: How to Install Lombok Plug-in for Eclipse, Specific Code Example Required Introduction: Eclipse is a widely used integrated development environment (IDE) for Java development. Lombok is a Java library that can automate some tedious code to improve development efficiency. This article will detail how to install the Lombok plug-in in Eclipse and provide specific code examples. Step 1: Download the Lombok plug-in, open Eclipse, and select "Help

Practical tips: How to easily install the Lombok plug-in in Eclipse, specific code examples are required. In daily Java development, we often use Eclipse as the main integrated development environment. In actual development, we may encounter some tedious operations, such as manual writing of Getter and Setter methods. To simplify these operations, we can use the Lombok plug-in to automatically help us generate these codes. Here's how to easily install and configure it in Eclipse

What is Lombok? Lombok is a Java library designed to reduce code development efforts. It provides some simple annotations to eliminate bloated template code in Java, such as the most common setter/getter methods in pojo, such as toString method, equals method, etc. It can also help us close the stream, even if JDK7 There are already TWR features in , but this package is well worth checking out. Through a few simple annotations, the template code is written into the program during compilation. You can see the generated method in the Outline window using eclipse, but it is clean in the source code. For installation, first go to the lombok official website to download the jar package. Just download the jar package

Java is a commonly used programming language that is widely used to develop various types of applications. Java API is one of the core parts of the Java language. It provides developers with many reusable codes and libraries that can speed up the application development and deployment process. During the development process of Java API, it is often necessary to use some tools and techniques to simplify coding to improve the readability and maintainability of the code. Lombok is a very practical Java library that can be used in Java

Annotation examples 1. @ToString: implements toString() method 2. @Data: annotated on the class; provides getting and setting methods for all attributes of the class. In addition, equals, canEqual, hashCode, and toString methods are provided. 3. @Setter: annotation On properties; provide setting methods for properties. @Getter: Annotated on the attribute; provides a getting method for the attribute @Log4j: Annotated on the class; provides a log4j log object with an attribute named log for the class @NoArgsConstructor: Annotated on the class; provides a parameterless constructor for the class @All
