MyBatis 결과 매핑 에러 해결2
Mybatis 사용중, 쿼리 결과가 dto 에 제대로 매핑이 안되는 오류가 발생했다2
이번에도 mismatch 에러다.
Error instantiating class com.example.springboard.domain.boards.Board with invalid types (int,String,BoardAccessAuthority) or values (1,all_board,1).
Cause: java.lang.IllegalArgumentException: argument type mismatch
Board 객체를 가져올 때, Board 객체의 필드인 AccessAuthority 를 join 해서 가져오도록 하는 과정에서 발생한 에러이다.
코드는 다음과 같다.
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package com.example.springboard.domain.boards;
import com.example.springboard.domain.BaseEntity;
public class Board extends BaseEntity {
private int id;
private String title;
private BoardAccessAuthority boardAccessAuthority;
public Board(int id, String title, BoardAccessAuthority boardAccessAuthority) {
this.id = id;
this.title = title;
this.boardAccessAuthority = boardAccessAuthority;
}
static Board of(int id, String title, BoardAccessAuthority boardAccessAuthority) {
return new Board(id, title, boardAccessAuthority);
}
public int getId() {
return id;
}
public String getTitle() {
return title;
}
public BoardAccessAuthority getBoardAccessAuthority() {
return boardAccessAuthority;
}
public void setId(int id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setBoardAccessAuthority(
BoardAccessAuthority boardAccessAuthority) {
this.boardAccessAuthority = boardAccessAuthority;
}
}
public class BoardAccessAuthority {
private int id;
private String accessLevel;
public BoardAccessAuthority(int id, String accessLevel) {
this.id = id;
this.accessLevel = accessLevel;
}
static BoardAccessAuthority of(int id, String accessLevel) {
return new BoardAccessAuthority(id, accessLevel);
}
public int getId() {
return id;
}
public String getAccessLevel() {
return accessLevel;
}
public void setAccessLevel(String accessLevel) {
this.accessLevel = accessLevel;
}
public void setId(int id) {
this.id = id;
}
}
Mapper xml 을 다음과 같이 구성됐다.
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
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springboard.mapper.BoardMapper">
<resultMap id="boardAccessAuthorityResultMap"
type="com.example.springboard.domain.boards.BoardAccessAuthority">
<result column="board_access_authority_id" property="id"/>
<result column="access_level" property="accessLevel"/>
</resultMap>
<resultMap id="boardResultMap" type="com.example.springboard.domain.boards.Board">
<result column="title" property="title"/>
<result column="id" property="id"/>
<collection property="boardAccessAuthority" resultMap="boardAccessAuthorityResultMap"/>
</resultMap>
<select id="findAll" resultMap="boardResultMap">
SELECT a.id,
a.title,
b.id as board_access_authority_id,
b.access_level
FROM boards a
INNER JOIN board_access_authorities b ON a.access_authority_id = b.id
</select>
</mapper>
클래스와 매퍼의 코드에는 문제가 없어보이는데 왜 board 를 찾은 결과가 제대로 dto 에 매핑이 되지 않는걸까
원인은 간단했다. 기본 생성자가 없었기 때문이다.
앞선 글에서 살펴봤듯이, 기본 생성자가 없다면 제대로 객체의 생성이 이루어지지 않는다.
혹시라도 join 을 이용해 연관 관계에 있는 객체를 eager fetch 하는 경우 나같은 문제를 겪는 사람은 생성자를 다시 살펴보기 바란다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.