在使用MyBatis的时候,若实体类上使用了lombok的@Builder注解,那么在查询数据做映射的时候会出现Cannot determine value type from string 'xxxxxx'
错误,产生这个错误的原因是当使用了@Builder注解之后会默认把无参构造方法忽略掉,创建一个全参的构造方法,比如
import java.io.Serializable;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class DemoBean implements Serializable {
private Long id;
private String name;
}
被编译之后再反编译,变成了:
import java.io.Serializable;
public class DemoBean implements Serializable {
private Long id;
private String name;
DemoBean(Long id, String name) {
this.id = id;
this.name = name;
}
public static DemoBean.DemoBeanBuilder builder() {
return new DemoBean.DemoBeanBuilder();
}
// ...忽略setter、getter方法
public static class DemoBeanBuilder {
private Long id;
private String name;
DemoBeanBuilder() {
}
public DemoBean.DemoBeanBuilder id(Long id) {
this.id = id;
return this;
}
public DemoBean.DemoBeanBuilder name(String name) {
this.name = name;
return this;
}
public DemoBean build() {
return new DemoBean(this.id, this.name);
}
public String toString() {
return "DemoBean.DemoBeanBuilder(id=" + this.id + ", name=" + this.name + ")";
}
}
}
从代码看到是没有默认构造方法,而MyBatis进行映射的时候会需要无参构造方法实例化一个类,所以我们再使用@Builder的时候,即使使用@NoArgsConstructor注解也无济于事,那我们该怎么办?
在lombok中有一个@Tolerate注解,我们看下它的定义
/**
* Put on any method or constructor to make lombok pretend it doesn't exist,
* i.e., to generate a method which would otherwise be skipped due to possible conflicts.
*/
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.SOURCE)
public @interface Tolerate {
}
注释上的意思就是让lombok在扫描的时候假装被@Tolerate修饰的方法不存在,也就是会原封不动的被编译到字节码中,不会覆盖它,那么这样的话我们就可以进行骚操作了,修改原代码为:
import java.io.Serializable;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class DemoBean implements Serializable {
private Long id;
private String name;
@Tolerate
public DemoBean() {
}
}