개발 지식/기타
[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 애너테이션만 사용 시 롬복에서 자동으로 모든 매개변수를 포함한 생성자를 생성한다.