实体类仅使用lombok@Builder导致的mybatis-plus查询结果集映射异常
问题复现
实体类代码:UserInfoEntity.java
@Builder
@Data
@TableName("user_info")
public class UserInfoEntity {
private Long id;
private String name;
private String age;
private String creator;
private LocalDateTime gmtCreated;
private String modifier;
private LocalDateTime gmtModified;
private String phone;
}
数据库user_info表结构
id |name |age |phone |creator|gmtCreated |modifier |gmtModified |
---+------------+----+---------+-------+-------------------+---------+--------------------+
1|张三 |18 | |SYSTEM |2024-09-06 16:52:23|SYSTEM |2024-09-06 16:52:23|
1|李四 |22 | |SYSTEM |2024-09-10 17:52:23|SYSTEM |2024-09-11 11:33:01|
使用Mybatis-plus BaseMapper.selectById()方法,异常报错:
org.springframework.dao.DataIntegrityViolationException: Error attempting to get column 'creator' from result set.
Cause: java.sql.SQLDataException: Cannot convert string 'SYSTEM' to java.sql.Timestamp value
排查过程
SYSTEM
是库表中creator
字段的存储值,异常报错信息中显示SYSTEM
被映射到日期时间类字段;UserInfoEntity.java
中的时间类字段是gmtCreated
和gmtModified
,判断可能和实体类字段顺序与数据库字段顺序不一致有关,实际验证调整字段顺序确实可以解决;还原2进行的调整,问题复现,初步确认是字段顺序问题引发的;
原因分析
仅使用@Builder会使entity只有全参构造器,缺少无参构造器时Mybatis Plus会调用全参构造器,按照顺序映射结果,当实体类与数据库字段顺序不一致时,就可能出现问题。
解决办法:@Builder
注解配合@AllArgsConstructor
、@NoArgsConstructor
一起使用
注:只加@NoArgsConstructor
会编译期报错,因为@Builder
本质是依赖类的 Constructor工作,在没有声明Constructor时缺省使用weak @AllArgsConstructor
,但缺省会被显式声明给覆盖,所以@Builder
与@NoArgsConstructor
的基础上要加上@AllArgsConstructor
参考文章:
https://blog.csdn.net/tianmaxingkonger/article/details/128441369