Spring Framework
[MapStruct] 필드 매핑할 때 다른 Mapper 클래스의 메소드 사용하는 법 - uses, @Named
개발자 이우진
2024. 8. 7. 17:34
상황
UserDto.unlockingConstellation
을 매핑할 때 UserConstellationMapper.toDto(UserConstellation)
를 사용해서 매핑하려고 한다. 자동으로 생성된 코드에서는 UserDto.unlockingConstellation.constellation
까지 .get()
하여 의도하지 않은 SELECT
가 발생하기 때문이다.
public class UserDto {
...
/**
* 현재 해금중인 유저 별자리 상태
*/
private UserConstellationDto unlockingConstellation;
}
@Mapper(componentModel = "spring", uses={UserConstellationMapper.class})
public interface UserMapper {
...
// ! 이렇게 해도 UserMapperImpl에서 UserConstellationMapper를 참조하지 않는다
@Mapping(target = "unlockingConstellation", source = "unlockingConstellation")
UserDto toDto(User user, UserConstellation unlockingConstellation);
}
해결법
UserMapper
에@Mapper(uses={UserConstellationMapper.class})
를 추가해서 다른 Mapper 클래스를 불러오게 한다- 불러올 클래스와 메소드에
@Named
로 별명을 붙여 준다. 클래스에도 추가해야 한다. - 매핑할 필드에서
qualifiedByName = {"클래스 별명", "메소드 별명"}
을 추가해 준다.
이렇게 하면 자동으로 생성된 UserMapperImpl
에서 UserConstellationMapper
멤버 변수를 추가해서 의존성을 주입하고 userConstellationMapper.toDto()
를 호출한다.
@Mapper(componentModel = "spring")
@Named("UserConstellationMapper")
public interface UserConstellationMapper {
...
@Mapping(target = "constellation", ignore = true)
@Named("toDto(UserConstellation)")
UserConstellationDto toDto(UserConstellation userConstellation);
...
}
@Mapper(componentModel = "spring", uses={UserConstellationMapper.class})
public interface UserMapper {
...
@Mapping(target = "unlockingConstellation", source = "unlockingConstellation", qualifiedByName = {"UserConstellationMapper", "toDto(UserConstellation)"})
UserDto toDto(User user, UserConstellation unlockingConstellation);
}
출처
MapStruct 공식 문서 - 5.9. Mapping method selection based on qualifiers