一、问题现象
使用MyBatis查询数据在数据映射环节发生异常:
org.springframework.dao.DataIntegrityViolationException
(表象异常)数据完整性约束异常,通常在数据更新/插入时,数据类型不匹配引起
com.mysql.cj.exceptions.DataConversionException
(根异常)数据转换时发生异常
主要报错信息:
org.springframework.dao.DataIntegrityViolationException: Error attempting to get column 'user_id' from result set.
Cause: java.sql.SQLDataException: Unsupported conversion from LONG to java.time.LocalDateTime;
Unsupported conversion from LONG to java.time.LocalDateTime;
nested exception is java.sql.SQLDataException: Unsupported conversion from LONG to java.time.LocalDateTime] with root cause
com.mysql.cj.exceptions.DataConversionException: Unsupported conversion from LONG to java.time.LocalDateTime
二、问题原因
查询结果映射的Model使用了lombok的@
Builder注解,使用了该注解的类,会在编译时为该类只生成全参数的构造函数,不会生成无参构造函数,那么就必须在实例化该Model时通过构造函数赋值,如果返回的列与构造函数参数顺序不一致,就会导致该问题
1、问题代码示例:Model
- 源文件
@Builder
@Data
public class Order {
private long id;
private long user_id;
private LocalDateTime submit_time;
private int status;
/*省略其他字段*/
}
- 编译结果
可以在编译结果target目录中查看Order.class文件
public class Order {
private long id;
private long user_id;
private LocalDateTime submit_time;
private int status;
Order(final long id, final long user_id, final LocalDateTime submit_time, final int status) {
this.id = id;
this.user_id = user_id;
this.submit_time = submit_time;
this.status = status;
}
/*省略get、set方法*/
}
2、问题代码示例:Mapper
@Mapper
public interface OrderMapper {
@Select("SELECT id,user_id,status,submit_time FROM order")
List<Order> getAllOrder();
}
三、解决办法
可以通过添加无参构造函数,或者调整查询列顺序的方式解决问题,二者任选其一即可
1、注解添加无参构造函数(推荐)
使用@
NoArgsConstructor,@
AllArgsConstructor,让lombok Model同时具备全参数和无参数构造函数
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {
private long id;
private long user_id;
private LocalDateTime submit_time;
private int status;
/*省略其他字段*/
}
2、手动添加无参构造函数
手动添加构造函数,并使用@
Tolerate注解让lombok 忽略该构造函数
@Builder
@Data
public class Order {
private long id;
private long user_id;
private LocalDateTime submit_time;
private int status;
/*省略其他字段*/
@Tolerate
Order() {}
}
3、调整查询列的顺序
@Mapper
public interface OrderMapper {
@Select("SELECT id,user_id,submit_time,status FROM order")
List<Order> getAllOrder();
}