Lombok Getter/Setter Pitfalls with MyBatis and @Accessor(chain=true) Issues in EasyExcel
This article explains why Lombok-generated getter/setter methods for fields whose second character is uppercase can cause MyBatis to store null values, shows the MyBatis PropertyNamer logic that leads to the problem, and also describes how the @Accessor(chain=true) annotation interferes with EasyExcel's reflection‑based export, offering practical workarounds for both issues.
Last year the author introduced Lombok into a project to eliminate boilerplate code such as getters, setters, and toString methods, but later discovered that Lombok can generate getter/setter signatures that MyBatis does not recognize, causing certain fields to be persisted as null in the database.
Problem with Lombok-generated methods
When a field name starts with a lowercase letter followed by an uppercase letter (e.g., nMetaType ), Lombok creates getNMetaType() and setNMetaType() . MyBatis, however, expects getnMetaType() and setnMetaType() according to the JavaBeans specification. As a result, MyBatis fails to map the field and inserts null .
The author inspected MyBatis source (class PropertyNamer ) and showed the relevant method:
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;
}A test case demonstrates the conversion results:
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)));
// Output:
// 方法名字是:isName 属性名字:name
// 方法名字是:getName 属性名字:name
// 方法名字是:getnMetaType 属性名字:nMetaType
// 方法名字是:getNMetaType 属性名字:NMetaTypeSolutions for the Lombok issue
Rename the field so that the second character is lowercase (e.g., nmetaType ).
If the database schema cannot be changed, manually generate the correct getter/setter methods (or let the IDE generate them) for the problematic fields.
Problem with @Accessor(chain = true) in EasyExcel
When exporting data with EasyExcel, newly added entity classes annotated with @Accessor(chain = true) fail because EasyExcel relies on CGLIB’s BeanMap , which in turn uses Java’s Introspector . The introspector only recognises setter methods that return void , so the chainable setters (which return the object itself) are ignored.
Relevant snippet from CGLIB/Introspector (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);
}
}Solutions for the @Accessor issue
Remove the @Accessor(chain = true) annotation from the entity class.
Await an update from the EasyExcel maintainers to use a reflection utility that accepts non‑void returning setters, or replace the underlying CGLIB usage yourself.
--- End of article ---
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.