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.
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)
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.