본문 바로가기
[개발일기]

[Refactoring] @Builder와 Q-Type의 충돌

by dop 2021. 4. 14.

@Builder를 적용한 Entity

Spring Boot에서 다음과 같은 방법으로 어노테이션으로 편리하게 Builder패턴을 적용할 수 있었다.

@Embeddable
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder(builderMethodName = "addressBuilder")
@ToString(of = {"city", "street", "detail"})
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class Address {
    private String city;
    private String street;
    private String detail;

    public static AddressBuilder builder(String city, String street, String detail) {
        if(city == null || street == null || detail == null){
            throw new IllegalArgumentException("null argument exception");
        }
        return addressBuilder().city(city).street(street).detail(detail);
    }
}

테스트 코드를 실행해도 별 문제없이 동작했고, 심지어 부트 서버를 실행할 때도 정상적으로 작동했지만, 문제는 Querydsl 컴파일 시점에 나타났다. QAddress를 생성하는 시점에서 AddressBuilder라는 클래스를 찾을 수 없다는 오류가 발생했다. 직접 선언한게 아니라 @Builder(builderMethodName = "addressBuilder")에 의해서 어플리케이션 실행 시점에 클래스가 생성되는게 원인이라고 생각되었기 때문에 아래와 같이 수정할 수 밖에 없었다.

@Embeddable
@ToString(of = {"city", "street", "detail"})
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public class Address {
    private String city;
    private String street;
    private String detail;
}

코드가 더 짧아져서 좋다고 생각하긴 이르다. 이전 방식은 객체 생성시 필수 값과 선택값을 제한할 수 있는 장점이 있었는데, 그런 것 없이 모든 값을 ".name().email()" 이런 방식으로 할당해야 한다. 빌더 패턴의 장점을 절반만 이용하게 된 것 같아 찝찝하지만 일단은 이렇게 작성한 채로 넘어가겠다. 이후에 더 좋은 방법이나 Querydsl 컴파일시 우회할 수 있는 방법을 알게된다면 적용하기로 하자!

728x90