왜 mapstruct는 boolean 타입인 is 접두사가 붙은 필드를 변환하지 못할까?

junto·2024년 7월 6일
0

spring

목록 보기
23/30
post-thumbnail

문제

  • mapstruct에서 is 접두사가 붙은 필드를 인식하지 못한다. 왜 필드 이름이 같은데도 mapstruct에서는 인식하지 못할까?
warning: Unmapped target property: "isTotpEnabled".

원인

  • mapstruct가 LomBok이 만들어준 getter를 인식하지 못해서 발생하는 문제인데, 먼저 Lombok의 동작 방식을 알아보자.

1. Lombok 동작 방식

  • boolean 타입의 경우
    • getter 앞에 "is" prefix가 붙는다.
    • 이미 변수에 "is" prefix가 있다면, prefix가 붙지 않는다.
  • Boolean 타입의 경우
    • getter 앞에 "get" prefix가 붙는다.
  • delombok해보면 생성된 getter는 아래와 같았다.
    public boolean isTotpEnabled() {
    	return this.isTotpEnabled;
    }
    
    public Boolean getIsTotpEnabled() {
    	return this.isTotpEnabled;
    }
    
  • Boolean 타입에서는 get 접두사가 붙기 때문에 문제가 되지 않지만, boolean 타입에서는 접두사가 붙지 않기 때문에 문제가 발생한다.

2. mapstruct 동작 방식

  • mapStruct는 is접두사가 붙은 boolean 필드에 대해서 Lombok과 동작 방식이 다르다. mapstruct는 is접두사가 붙은 필드에 값을 알아내기 위해 isIsTotpEnabled() 또는 getIsTotpEnabled()를 호출하고 있었다. 아래와 같이 getter를 만들어주면 mapstruct가 정상적으로 매핑한다.
      public boolean isIsTotpEnabled() {
    	  return this.isTotpEnabled;
      }
    
      public boolean hasIsTotpEnabled() {
    		return this.isTotpEnabled;
      }
  • 즉, boolean 타입에 대해 “is” prefix가 붙은 필드는 lombok이 만든 getter와 mapstruct가 찾는 getter가 다르기 때문에 문제가 발생한다.

해결 방법

  • Lombok을 사용하기 때문에 위에처럼 getter를 새로 만드는 건 lombok 사용 취지에 맞지 않는다.

1) 기존 boolean isTotpEnabled 유지하기

  • mapstruct에서 mapping 옵션을 추가한다. mapstruct가 Lombok이 만들어주는 getter를 사용하기 위해 아래처럼 source 필드를 수정한다.
  @Mapping(source = "totpEnabled", target = "isTotpEnabled")
  ResHello toResTotp(User user);
  

2) 기존 boolean isTotpEnabled → totpEnabled로 수정하기

  • mapstruct에 따로 mapping 설정을 할 필요가 없다.

3) 기존 boolean 타입을 Boolean 타입으로 수정하기

  • Boolean 타입으로 변경하면 getter 메서드는 has접두사가 붙고, 이는 mapstruct가 인식하는 방법과도 동일하다.
  • 별도로 매핑을 설정할 필요가 없고, 기존 변수 네이밍을 유지할 수 있다.

3번 방법인 Boolean 타입을 적용하기로 했다.

  • 1번 방식은 매번 수동으로 매핑하기엔 번거롭고, 2번은 변수명을 모두 수정해야 한다. 3번은 언박싱 오버헤드가 있겠지만 Boolean 배열이 아니므로 위 방법을 적용하기로 했다.
  • is, has, can 등 접두사를 붙이면 변수 이름만으로도 타입을 알 수 있다. IDE가 똑똑한 지금은 필요성이 과거보다 덜 해졌지만 나는 이 방식이 의미도 더 분명히 전달하는 거 같아 선호한다. 중요한 건 어떤 방식을 적용했든 기존 컨벤션을 일관성 있게 지키는 것이라 생각한다.

참고 자료

profile
꾸준하게

0개의 댓글