Cannot Determine Value Type From String 'Xxxxxx'

在使用MyBatis的时候,若实体类上使用了lombok的@Builder注解,那么在查询数据做映射的时候会出现Cannot determine value type from string 'xxxxxx'错误,产生这个错误的原因是当使用了@Builder注解之后会默认把无参构造方法忽略掉,创建一个全参的构造方法,比如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.io.Serializable;

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class DemoBean implements Serializable {

private Long id;

private String name;

}

被编译之后再反编译,变成了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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注解,我们看下它的定义

1
2
3
4
5
6
7
8
/**
* 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修饰的方法不存在,也就是会原封不动的被编译到字节码中,不会覆盖它,那么这样的话我们就可以进行骚操作了,修改原代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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() {
}

}