Entity객체를 생성할 때 lombok의 @Builder를 많이 적용한다.
@Builder를 사용할경우, 일반적으로 기본 생성자에 대한 접근 제어를 위해
@NoArgsConstructor(access = AccessLevel.PROTECTED)
를 사용한다.
이유: 무분별하게 생성되는 객체들을 한번 더 체크하면서 의도하지 않은 Entity 객체를 만드는 행위 방지!
근데 @Builder와 @NoArgsConstructor을 동시에 사용하면 컴파일 에러가 난다.
▶왜 컴파일 에러가 발생함??
@Builder를 통해 필요한 파라미터만 받아서 객체 생성 가능, 전체 파라미터를 받아서 객체 생성 가능
-> 전체 생성자가 없으면 당연히 에러가 발생함.
▷@NoArgsConstructor없이 @Builder만 사용하면 에러 안뜨는디??
@Builder 내부를 보면
@~ArgsConstructor 을 추가하지 않은 경우
-> @Builder가 모든 필드를 파라미터로 사용하는 생성자를 생성(@AllArgsConstructor과 같은 역할)
@NoArgsConstructor이나 다른 생성자들이 존재함
-> @AllArgsConstructor을 사용해서 전체 생성자를 만들어줘야함.
혹시 @~ArgsConstructor 어노테이션을 잘 모르겠으면
위 글을 참고하시길!!! 바랍니다!!!
따라서 @Builder를 클래스단에 붙여주기 위해서는 @AllArgsConstructor과 @NoArgsConstructor을 함께 붙여줘야한다!
안그러면 오류뜬다!
▶ 만약 @AllArgsConstructor 사용을 "지양"하신다면...?
만약 당신이 @AllArgsConstructor 사용을 "지양"한다..!!
고 하면....그럼 어떻게하지...?
▷생성자에 @Builder를 붙이자!
@Builder를 클래스에 적용하는 것 = 클래스에 @AllArgsConstructor를 추가해야함.
이렇게 되면 위 블로그 글에서 설명한 문제에, 추가로
객체 생성 시 받지 않아야 할 매개변수들도 빌더 패턴에 의해 노출 되게 된다.
때문에 필요한 매개변수만으로 생성자를 만들고, 그 생성자에 @Builder 어노테이션을 넣을 것을 권장한다.
(롬복 공식 문서에 따르면, 명시적 생성자가 "있는 경우", 클래스 선언부가 아닌 명시적 생성자에 @Builder 어노테이션을 넣을 것을 가이드하고 있다.)
@Entity
@Getter
@Table(name = "order")
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 생성자를 통해서 값 변경 목적으로 접근하는 메시지들 차단 (다른 패키지에 소속된 클래스는 접근 제한)
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@Column
private int quantity;
@Column
private int price;
}
이렇게 클래스단에 @Builder와 @AllArgsConstructor을 붙이지 않고
@Entity
@Getter
@Table(name = "order")
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 생성자를 통해서 값 변경 목적으로 접근하는 메시지들 차단 (다른 패키지에 소속된 클래스는 접근 제한)
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@Column
private int quantity;
@Column
private int price;
@Builder
protected Order(Long id, String name, int quantity, int price) {
this.id = id;
this.name = name;
this.quantity = quantity;
this.price = price;
}
}
따로 생성자를 만들어서 그 위에 @Builder를 붙이는 방식을 사용하면 된다!