MapStruct 사용기

진주원(JooWon Jin)·2023년 11월 28일
0

TWTW

목록 보기
3/8
post-thumbnail

MapStruct 에서 2개 이상의 인자 사용

MapStruct

Java Bean 유형 간의 매핑 구현 단순화하는 코드 생성기

특징

  1. 컴파일 시점에 코드 생성
  2. 반복적 구현을 줄여준다.
  3. Annotation processor를 이용하여 객체 간 매핑 자동화
  4. MapStruct는 Lombok의 Getter,Setter,Builder를 이용한다.
    1. 꺼내오는 객체 → Getter 필요
    2. 저장하는 객체 → Builder OR 모든 필드를 포함하는 생성자

상황

MapStruct를 통해 DTO ↔ Entity 변환 과정을 수행하고 있었다. Group 을 생성하는 로직에 있어 개선점을 필요로 하였다.

Group

@Entity
@Getter
@Where(clause = "deleted_at is null")
@EntityListeners(AuditListener.class)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Group implements Auditable {
    @Id
    @GeneratedValue(generator = "uuid2")
    @Column(name = "id", columnDefinition = "BINARY(16)")
    private UUID id;

    private String name;
    private String groupImage;

    private UUID leaderId;
}
  • 다음은 Group Entity의 일부이다. 핵심은 그룹 장의 정보를 알 수 있는 leaderId가 포함되어 있는 것이다.
  • leaderId를 기존에는 MakeGroupRequest에서 인자로 받고 있었다.

MakeGroupRequest

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class MakeGroupRequest {
    private String name;
    private String groupImage;
    private UUID leaderId;
}
  • 하지만 내부 회의를 하면서 그룹을 만드려고 접근한 사용자가 leader일 것이고 추가적으로 Id를 별도로 입력 받는 것은 TOO MUCH라고 판단하였다.

결국 해당 인자를 제거하고 로직을 짜야 하는데 MapStruct 상의 변화가 필요하다 !!!!

오류

@Mapping(target = "name", source = "name")
@Mapping(target = "groupImage", source = "groupImage")
**@Mapping(target = "leaderId", source = "leaderId")**
@Mapping(target = "baseTime", ignore = true)
@Mapping(target = "groupMembers", ignore = true)
@Mapping(target = "groupPlans", ignore = true)
Group toGroupEntity(MakeGroupRequest groupDto, UUID leaderId);
  • leaderId를 읽어올 수 없다는 오류가 계속해서 발생하였다.

원리

2개 이상의 인자를 MapStruct를 통해 변환하기 위해서는 해당 인자(source)가 어느 인자 객체에서 왔는지 명시해줘야 한다. MakeGroupRequest에서 name과 groupImage를 받아오기 때문에 source명을 “groupDto.XXX” 이렇게 표기해줘야 한다.

수정

@Mapping(target = "baseTime", ignore = true)
@Mapping(target = "groupMembers", ignore = true)
@Mapping(target = "groupPlans", ignore = true)
@Mapping(target = "name",source = "groupDto.name")
@Mapping(target = "groupImage", source = "groupDto.groupImage")
@Mapping(target = "leaderId", source = "leaderId")
Group toGroupEntity(MakeGroupRequest groupDto, UUID leaderId);
  • 인자가 2개 이상일 경우 source의 표시를 객체부터 시작해야 한다.
profile
Young , Wild , Free

0개의 댓글