본문 바로가기
Java & Spring

Lombok 안전 사용 규칙(@Builder/@Value/@With)

by yamoojin83 2025. 10. 1.

Lombok 안전 사용 규칙(@Builder/@Value/@With)

Lombok은 보일러플레이트를 크게 줄여줍니다.

하지만 무심코 @Data를 붙이거나 @Builder 디폴트값/불변성 규칙을 놓치면

생산성보다 버그가 앞서옵니다. 아래 규칙은 “팀에서 Lombok을 안전하게 쓰기 위한 최소 합의”입니다.

1) @Data 남용 금지

@Data모든 필드를 대상으로 equals/hashCode/toString을 생성합니다. 엔티티/DTO에 무분별하게 쓰면 성능/보안(PII 노출) 문제가 생깁니다. 대신 @Getter + 필요한 것만 @EqualsAndHashCode(of="id") 같이 선별하세요.

2) @Builder 기본값 규칙


@Builder
public class User {
  private final String id;
  @Builder.Default private final Role role = Role.USER; // ✅ 디폴트 보존
}

@Builder.Default 없이 디폴트를 설정하면 빌더가 null로 덮어쓰는 문제가 생깁니다. 또한 불변 필드에 null이 들어가지 않도록 @NonNull을 병행합니다.

3) @Value(불변)와 컬렉션


@Value
public class Profile {
  String name;
  List<String> tags; // ⚠️ 리스트 자체는 가변
  public Profile(String name, List<String> tags) {
    this.name = name;
    this.tags = List.copyOf(tags); // 방어적 복사로 불변 보장
  }
}

@Value는 필드를 final로 만들지만, 컬렉션 내용까지 불변으로 바꾸진 않습니다. 방어적 복사/불변 래핑으로 외부 변경을 차단하세요.

4) @With로 부분 변경 모델링


@Value @With
public class Money {
  long amount; String currency;
}
// 사용: money.withAmount(2000)

@With는 불변 객체의 “값 한두 개만 바뀐 복사”를 우아하게 만듭니다.

5) Jackson/JPA와의 궁합

  • Jackson: DTO에 @NoArgsConstructor가 필요할 수 있습니다(필요 시만). record를 쓰면 NoArgs 없이도 잘 동작합니다.
  • JPA: 엔티티에는 Lombok의 @Builder보다 명시적 생성자를 권장. @EqualsAndHashCode는 식별자만 기준으로.

6) Delombok/구성 파일


# lombok.config (루트)
lombok.addLombokGeneratedAnnotation = true
lombok.equalsAndHashCode.callSuper = skip
lombok.anyConstructor.suppressConstructorProperties = true

CI에서 delombok을 돌려 생성 결과를 확인하면 문제를 조기 발견할 수 있습니다.

7) @Builder와 검증 조합


@Getter @Builder
public class SignUp {
  @NonNull String email;
  @NonNull String password;
  public SignUp(String email, String password) {
    if (!email.contains("@")) throw new IllegalArgumentException("email");
    if (password.length() < 8) throw new IllegalArgumentException("pwd");
    this.email = email; this.password = password;
  }
}

빌더가 생성자를 우회하지 않도록 “필수 검증은 생성자에서” 수행하세요.

요약 체크리스트

  • @Data 금지, 필요한 애노테이션만 선택
  • @Builder.Default로 디폴트 보존
  • 불변 + 컬렉션은 방어적 복사
  • @With로 부분 변경
  • Jackson/JPA 요구사항 분리, 테스트로 확인

 

 

👉 1편: Maven→Gradle 마이그레이션 함정 7가지

👉 2편: JUnit5 + Mockito: Given-When-Then 패턴

👉 3편: Lombok 안전 사용 규칙(@Builder/@Value/@With)

👉 4편: IntelliJ 생산성: 라이브 템플릿 10개