记录一个坑
在使用mybatisplus时候,实体类使用@Builder,然后在运行查询语句时候出现下面错误
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1
1、排查原因
查看sql语句没有问题
SELECT max(id) as id FROM t_campus_message WHERE (msg_status <> ? AND from_id <> ? AND from_id = ? OR to_id = ?) GROUP BY conversation_id ORDER BY id DESC LIMIT ?
发现没有问题,在数据库可以查到数据
但是想到映射的实体类 加了Lombock注解
@Data
@Builder
public class Message implements Serializable {
然后查看class反编译的代码
发现只有有参构造
Message(final Long id, final Long fromId, final Long toId, final String conversationId, final String msgContent, final Integer msgStatus, final Long fileId, final Date createdTime) {
this.id = id;
this.fromId = fromId;
this.toId = toId;
this.conversationId = conversationId;
this.msgContent = msgContent;
this.msgStatus = msgStatus;
this.fileId = fileId;
this.createdTime = createdTime;
}
2、总结原因
我们会发现与原本不使用Lombok的实体类相比,该类只有一个全参数的构造方法,而原本我们手写实体类时只写了getter和setter方法,所以编译后会默认带一个无参构造。 而上述使用Lombok的@Builder注解后,编译后实体有全参数的构造方法,那么编译器就不会再默认提供一个默认的无参构造。 所以问题可能就出现在这个无参构造方法缺失上,mybatis在将查询结果映射成实体时是通过无参构造获得一个实例,然后调用setter方法将值存入相应字段的。
3、解决方法
在实体类上加上@AllArgsConstructor
@NoArgsConstructor,使编译出来的代码加上无参构造
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor