개발 지식/기타

[Lombok] @Builder와 @AllArgsConstructor 사용시 주의사항

서하빈 2023. 11. 21. 14:45

- 클래스 내에서 특정 필드의 값을 초기화 시킨 후 @Builder와 @AllArgsConstructor를 사용하여 객체를 생성할 때 이미 초기화가 된 필드를 제외하는 경우 그 필드의 값은 다시 null로 초기화가 된다.

 

예시 코드

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@AllArgsConstructor
@Entity
public class Member extends Auditable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long memberId;

    @Column(nullable = false, length = 100)
    private String email;

    @Enumerated(value = EnumType.STRING)
    @Column(nullable = false, length = 100)
    private MemberStatus memberStatus = MemberStatus.MEMBER_ACTIVE;
}

 

public class Test {
	public static void main(String[] args) {
		Member member = Member.builder()
				.email("hgd@gmail.com")
				.build();

		System.out.println(member.getMemberStatus()); // null
	}
}

 

Member 클래스 내부에서 memberStatus 필드의 값을 active 값으로 초기화 해놨지만 builder 패턴으로 객체를 생성할 때 AllArgsConstructor 생성자를 사용하고 해당 필드를 제외하고 객체를 생성하기 때문에 다시 null로 초기화됨을 알 수 있다.

 

 

해결방안

- @AllArgsConstructor 대신에 memberStatus와 같이 초기화가 되어 있는 필드를 제외한 생성자를 만들고 이에 빌더 패턴을 적용해야 한다!!!!

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class Member extends Auditable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long memberId;

    @Column(nullable = false, length = 100)
    private String email;

    @Enumerated(value = EnumType.STRING)
    @Column(nullable = false, length = 100)
    private MemberStatus memberStatus = MemberStatus.MEMBER_ACTIVE;
    
    @Builder
    public Member(Long memberId, String email) {
    	this.memberId = memberId;
        this.email = email;
    }
}

 

 

!!! 추가로 클래스에 @Builder 애너테이션만 사용 시 롬복에서 자동으로 모든 매개변수를 포함한 생성자를 생성한다.