Backend Development 9 min read

Lombok Getter/Setter Naming Issues with MyBatis and @Accessor(chain=true) Problems in EasyExcel

This article explains how Lombok's generated getter and setter method names can conflict with MyBatis property resolution and cause issues when using EasyExcel's @Accessor(chain=true) annotation, and provides detailed code examples and solutions to resolve these incompatibilities.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Lombok Getter/Setter Naming Issues with MyBatis and @Accessor(chain=true) Problems in EasyExcel

Last year we introduced the Lombok plugin to reduce boilerplate code such as getters, setters, and toString methods, but we encountered several pitfalls that were not immediately obvious.

Setter‑Getter Method Pitfall

Problem Discovery

Using Lombok's @Data annotation, we faced an issue when inserting data with MyBatis: the nMetaType field was always persisted as null in the database.

@Data
public class NMetaVerify {
    private NMetaType nMetaType;
    private Long id;
    // ... other fields
}

During debugging, the nMetaType property held a value in the object, but after the insert the column remained null . Investigation revealed that MyBatis uses reflection to call getter/setter methods, and the method names generated by Lombok for a property whose first letter is lowercase and second letter is uppercase differ from the Java‑Bean convention.

Root Cause

Lombok generates getNMetaType and setNMetaType (capital N ), while the standard Java convention expects getnMetaType and setnMetaType (lowercase n ). MyBatis follows the latter, so it cannot locate the property.

// Lombok‑generated methods
public class NMetaVerify {
    private Long id;
    private NMetaType nMetaType;
    private Date createTime;

    public void lombokFound() {
        NMetaVerify nMetaVerify = new NMetaVerify();
        nMetaVerify.setNMetaType(NMetaType.TWO); // note the capital N
        nMetaVerify.getNMetaType(); // capital N as well
    }
}

Standard Java/IDE/MyBatis generated methods:

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() { // lower‑case n
        return nMetaType;
    }
    public void setnMetaType(NMetaType nMetaType) { // lower‑case n
        this.nMetaType = nMetaType;
    }

    public Date getCreateTime() { return createTime; }
    public void setCreateTime(Date createTime) { this.createTime = createTime; }
}

MyBatis PropertyNamer Source (simplified)

public final class PropertyNamer {
    private PropertyNamer() {}

    public static String methodToProperty(String name) {
        if (name.startsWith("is")) {
            name = name.substring(2);
        } else if (name.startsWith("get") || name.startsWith("set")) {
            name = name.substring(3);
        } else {
            throw new ReflectionException("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'.");
        }
        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;
    }
    // other helper methods omitted for brevity
}

Test Demonstrating the Conversion

@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("Method: " + methodName + " Property: " + PropertyNamer.methodToProperty(methodName)));
}

Output:

Method: isName Property: name 
Method: getName Property: name 
Method: getnMetaType Property: nMetaType 
Method: getNMetaType Property: NMetaType

@Accessor(chain = true) Annotation Issue

Problem Discovery

When exporting data with EasyExcel, newly added entity classes that include the Lombok annotation @Accessor(chain = true) stopped working correctly. The annotation enables fluent chaining of setter calls, e.g.:

new UserDto()
    .setUserName("")
    .setAge(10)
    .setBirthday(new Date());

Root Cause

EasyExcel relies on CGLIB's BeanMap for reflection. CGLIB ultimately uses the JDK's Introspector class, which only recognises setter methods that return void . The chained setters generated by Lombok return the object itself, so they are ignored, leading to missing property values during export.

// Simplified snippet from Introspector.java (line 520)
if (int.class.equals(argTypes[0]) && name.startsWith(GET_PREFIX)) {
    pd = new IndexedPropertyDescriptor(this.beanClass, name.substring(3), null, null, method, null);
} else if (void.class.equals(resultType) && name.startsWith(SET_PREFIX)) {
    pd = new PropertyDescriptor(this.beanClass, name.substring(3), null, method);
    if (throwsException(method, PropertyVetoException.class)) {
        pd.setConstrained(true);
    }
}

Solution

Remove the @Accessor(chain = true) annotation from the entity class.

Alternatively, wait for EasyExcel to replace CGLIB with a reflection library that supports non‑void returning setters.

---

Thank you for reading; hope this helps! (Source: juejin.cn/post/6881432532332576781)

JavaMyBatisEasyExcelLombokCglibGetterSetter
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.