이번 프로젝트에서 객체와 dto간의 변환을 위해 MapStruct를 사용하였다.
생성자를 이용하여 변환해주는 방법이 있지만 새로운 라이브러리를 활용하고 익숙해지는 연습을 하고, 코드를 더 깔끔하게 작성하여 가독성을 높이기 위해 적용해보았다.
그러던 중 게시글 관련 기능을 개발하던 중에 오류 메세지를 마주하게 되었다.
에러 메세지: nickname 필드를 매핑하지 못하고 있다.
Unmapped target property: "nickname". Mapping from property "Board reportBoard.board" to "BoardGetRes reportBoardGetRes.board".
Unmapped target property: "nickname". Mapping from Collection element "Comment reportBoard.board.comments" to "CommentGetRes reportBoardGetRes.board.comments".
에러가 발생한 mapper 코드는 다음과 같다.
@Mapper
public interface ReportBoardServiceMapper {
ReportBoardServiceMapper INSTANCE = Mappers.getMapper(ReportBoardServiceMapper.class);
@Mapping(source = "board.id", target = "reportedBoardId")
@Mapping(source = "user.id", target = "reporterUserId")
ReportBoardRes toReportBoardRes(ReportBoard reportBoard);
List<ReportBoardGetRes> toReportBoardListGetRes(List<ReportBoard> reportBoards);
}
Mapper는 변환 과정에서 필드의 이름이 같으면 자동으로 값을 대입해준다.
하지만 필드명이 다르다면 @Mapping을 사용해서 변환해줄 값을 지정하여 매핑시켜줄 수 있다.
이때 BoardGetRes의 nickname과
에러 발생 이유
List<ReportBoard>를 List<ReportBoardGetRes>로 변환하는 과정에서 오류가 왜 발생했는지 알아보기 위해서 두 객체 코드를 보자.
- ReportBoard
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "tb_boardreport")
public class ReportBoard extends TimeStamp {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column private String reason;
@ManyToOne
@JoinColumn(name = "boardId", nullable = false)
private Board board;
@ManyToOne
@JoinColumn(name = "userId", nullable = false)
private User user;
@Builder
private ReportBoard(Board board, User user, String reason) {
this.board = board;
this.user = user;
this.reason = reason;
}
}
필드로 Board, User, reason을 가지고 있다.
- ReportBoardGetRes
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ReportBoardGetRes {
private Long id;
private String reason;
private BoardGetRes board;
@Builder
private ReportBoardGetRes(Long id, String reason, BoardGetRes board) {
this.id = id;
this.reason = reason;
this.board = board;
}
}
필드로 id, reason, BoardGetRes를 가지고 있다.
첫 번째 오류에서는 Board를 BoardGetRes로 변환하는 과정에서 nickname이라는 필드를 매핑하지 못하고 있다.
따라서 다음 코드를 추가해줘야 한다.
@Mapping(source = "user.nickname", target = "nickname") // toReportBoardListGetRes 에서 필요
BoardGetRes toBoardGetRes(Board board);
사실 위의 코드는 BoardServiceMapper라는 곳에 존재한다.
그래서 처음에는 mapper가 자동으로 그곳에 있는 코드를 사용해여 변환 작업을 할 것이라고 생각했다.
하지만 다른 곳의 mapper를 가져오겠다는 추가적인 코드가 없는 상태에서는 한 mapper 내에서만 변환작업을 하기 때문에 이 곳에 추가해주어야 한다.
이를 통해서 한 메서드에서 매핑 작업을 할 때 같은 mapper에 존재하는 다른 매서드를 이용한다는 것을 알게 되었다.
두 번째 오류도 같은 맥락에서 발생했다.
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class BoardGetRes {
private String nickname;
private String title;
private String content;
private String fileURL;
private String departure;
private String destination;
private List<String> stopover;
private RegionEnum region;
private List<CommentGetRes> comments;
}
BoardGetRes에는 List<CommentGetRes> comments 필드가 존재한다.
따라서 Board 객체에 있는 Comment를 CommentGetRes 로 변환할 수 있도록 코드를 추가한다.
@Mapping(source = "user.nickname", target = "nickname") // toBoardGetRes 에서 필요
CommentGetRes toCommentGetRes(Comment comment);
즉 ReportBoardServiceMapper의 코드를 다음과 같이 수정해주면 오류를 해결할 수 있다.
@Mapper
public interface ReportBoardServiceMapper {
ReportBoardServiceMapper INSTANCE = Mappers.getMapper(ReportBoardServiceMapper.class);
@Mapping(source = "board.id", target = "reportedBoardId")
@Mapping(source = "user.id", target = "reporterUserId")
ReportBoardRes toReportBoardRes(ReportBoard reportBoard);
List<ReportBoardGetRes> toReportBoardListGetRes(List<ReportBoard> reportBoards);
@Mapping(source = "user.nickname", target = "nickname") // toReportBoardListGetRes 에서 필요
BoardGetRes toBoardGetRes(Board board);
@Mapping(source = "user.nickname", target = "nickname") // toBoardGetRes 에서 필요
CommentGetRes toCommentGetRes(Comment comment);
}
'TIL' 카테고리의 다른 글
[240117] ec2 서버 실행 (0) | 2024.01.17 |
---|---|
[240114] AWS, docker로 수동 배포하기 (0) | 2024.01.15 |
[240111] Docker image, Docker container (0) | 2024.01.11 |
[240110] CI/CD 공부 (1) CI (0) | 2024.01.10 |
[240108] Refresh Token 구현 전의 고려 사항 (0) | 2024.01.08 |