Table of Contents
Preface
The pitfalls of the Setter-Getter method
Problem discovery
Solution
Reason
Mybatis (version 3.4.6) parses the get-set method to obtain the source code of the attribute name:
Mybatis parses the get-set method to test the attribute name
@Accessor(chain = true) annotation problem
Home Java JavaBase Get to know the pitfalls of Lombok

Get to know the pitfalls of Lombok

Oct 09, 2020 pm 05:00 PM
lombok

java Basic Tutorial column introduces you to the pitfalls of Lombok, which is easy to use.

Get to know the pitfalls of Lombok

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;
    ....其他属性
}复制代码
Copy after login

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方法也是大写
    }
}复制代码
Copy after login
#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;
    }
}复制代码
Copy after login

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");
        }

}复制代码
Copy after login

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复制代码
Copy after login

Solution

1.修改属性名字,让第二个字母小写,或者说是规定所有的属性的前两个字母必须小写
2.如果数据库已经设计好,并且前后端接口对接好了,不想修改,那就专门为这种特殊的属性使用idea生成get-set方法复制代码
Copy after login

@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());复制代码
Copy after login

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);复制代码
Copy after login

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);
    }
}复制代码
Copy after login

Solution

1.去掉Accessor注解
2.要么就等待easyexcel的作者替换掉底层的cglib或者是其他,反正是支持获取返回值不是void的setxxx方法就行复制代码
Copy after login

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!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

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

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Pro Guidance: Expert advice and steps on how to successfully install the Eclipse Lombok plug-in Pro Guidance: Expert advice and steps on how to successfully install the Eclipse Lombok plug-in Jan 28, 2024 am 09:15 AM

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

Simple tutorial: Quickly install Lombok plug-in in Eclipse Simple tutorial: Quickly install Lombok plug-in in Eclipse Jan 28, 2024 am 08:06 AM

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

SpringBoot integrates Lombok and how to solve common problems SpringBoot integrates Lombok and how to solve common problems May 20, 2023 pm 12:46 PM

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 to Eclipse Lombok Plugin Installation Complete Guide to Eclipse Lombok Plugin Installation Jan 28, 2024 am 09:58 AM

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

Easy installation: Tips for installing Lombok plug-in in Eclipse Easy installation: Tips for installing Lombok plug-in in Eclipse Jan 28, 2024 am 09:29 AM

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

How to use Java library lombok and annotations How to use Java library lombok and annotations Jun 03, 2023 pm 09:28 PM

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

Using Lombok to simplify coding in Java API development Using Lombok to simplify coding in Java API development Jun 18, 2023 pm 11:34 PM

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

What annotations are there for Lombok in java? What annotations are there for Lombok in java? Apr 30, 2023 pm 03:52 PM

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

See all articles