개발(0)/JPA

💡 자주 쓰는 롬복(Lombok) 어노테이션과 패턴

까만밀가루 2025. 6. 12. 14:28

 

개인 프로젝트에 롬복을 쓰는데 습관처럼 쓰는데, 회사 직원이 물어보면서 다시 공부하게 된 롬복

여기서 다시 정리해봅니다

 


📋 Lombok 어노테이션 종류/역할

 

어노테이션 역할/설명 실무 사용 예
@Getter 모든 필드의 getter 자동 생성 거의 필수. DTO, Entity 모두에서 널리 사용
@Setter 모든 필드의 setter 자동 생성 Entity, DTO에서 불변성 지키고 싶으면 지양
@NoArgsConstructor 파라미터 없는 기본 생성자 자동 생성 JPA Entity 필수 (보통 access=PROTECTED)
@AllArgsConstructor 모든 필드를 파라미터로 받는 생성자 자동 생성 빌더와 같이 쓰기 필수! (access=PRIVATE 추천)
@RequiredArgsConstructor final/@NonNull 필드만 받는 생성자 자동 생성 서비스/컨트롤러 등 의존성 주입(DI)에서 가끔 사용
@Builder 빌더 패턴 자동 생성 (가장 많이 씀) 대부분 클래스 단위로 선언
@EqualsAndHashCode equals, hashCode 메서드 자동 생성 엔티티 PK, VO에서 가끔 사용
@ToString toString 메서드 자동 생성 로그/디버깅용, but 엔티티 연관관계 필드 주의!
@Data Getter/Setter, toString, equals, hashCode, RequiredArgsConstructor 자동 생성 편하긴 하지만, 실무에서는 거의

 


💡 @Data를 요즘 안 쓰는 이유?

1. 의도치 않은 setter/equals/hashCode 생성

  • @Data는 모든 필드에 Setter, equals, hashCode, toString까지 다 만들어줌
  • Entity/DTO에서 불변성을 깨뜨리거나, 연관관계 필드의 순환 참조(toString, equals 등)로 버그 발생 위험

2. 과도한 메서드 생성, 관리 어려움

  • 내가 원치 않는 메서드까지 자동 생성 → 디버깅, 유지보수 때 혼란

3. 실무 표준은 "명확하게 필요한 것만!"

  • @Getter, @NoArgsConstructor, @AllArgsConstructor, @Builder
    → 각 목적에 맞게 명확하게 조합해서 쓰는 게 실무 표준
  • Entity에는 Setter를 아예 안 쓰거나, 필요한 필드에만 개별로 붙임

🚩 내가 사용한 조합

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)  // JPA Entity 필수
@AllArgsConstructor(access = AccessLevel.PRIVATE)   // 빌더 생성자
@Builder                                            // 객체 생성 편의성
@Table(name = "survey")
public class Survey { ... }
 

 

- 기본적으로 생성하는 파라미터 없는 생성자 생성한 뒤 AllArgsConstructor과 Builder를 쓴다.

처음 Builder만 써야한다고 생각했는데 에러가 나서 AllArgsConstructor과 Builder에 대해 더 공부했다.

 

🔍 Q. @AllArgsConstructor, @Builder의 차이는?

A. 전체 파라미터 생성자 vs. 빌더 패턴

  • @AllArgsConstructor
    모든 필드를 파라미터로 받는 생성자를 만들어줌
    → 직접 new로 객체 생성
    → 필드가 많으면 가독성 떨어지고, 순서 잘못 넣으면 에러
Survey s = new Survey(1L, "설문제목", ...);
  • @Builder
    빌더 패턴을 자동 생성
    필요한 필드만 선택적으로 할당, 순서 상관 없이 명확하게 객체 생성
    → 내부적으로 “모든 필드 생성자”를 써서 객체를 만든다
Survey s = Survey.builder()
    .id(1L)
    .name("설문제목")
    .build();

 

 

B. 빌더는 '모든 필드 생성자'가 필수!

  • 빌더 패턴이 정상적으로 동작하려면
    모든 필드를 받는 생성자가 필요함
  • @NoArgsConstructor만 있으면, 이 생성자가 없어 에러 발생
  • 특정 생성자에만 붙이기도 가능:
    일부 파라미터만 빌더로 만들고 싶으면, 생성자에 직접 붙일 수도 있지만
    → 잘 안 씀 (유지보수 불리, 코드 일관성 떨어짐)
  • 해결:
    @AllArgsConstructor도 같이 선언하면 해결
    (실무에서는 @NoArgsConstructor + @AllArgsConstructor + @Builder 조합이 표준)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE) // 실수로 new 못하게!
@Builder
public class Survey { ... }

 

 

C. 두 어노테이션의 “핵심 차이점


  @AllArgsConstructor @Builder
생성 방법 new Survey(1L, "이름") Survey.builder().id(1L).name("이름").build()
파라미터 순서 반드시 지켜야 함 순서 상관 없음, 일부 필드만 선택 가능
가독성 낮음 (필드 많으면 헷갈림) 높음, 명확하게 필드별로 할당
유지보수 힘듦 (필드 추가/삭제 시 생성자 수정 필요) 쉬움 (필드 추가/삭제에도 코드 영향 적음)
필드 생략 불가 (모든 필드 값 필수) 가능 (필요한 것만 채워서 build 가능)

 

 

 


 

아직 실무에서 써본적은 없지만 앞으로를 위해 제대로 알아두면 좋을 거 같아 정리한 롬복

어노테이션이나 의존성을 필요할까봐 막 넣었다면 요즘은 최대한 사용하는 것 위주로 넣으려고 한다.(그래도 어려움)