참 골 때리는 어노테이션이기에 정리할 필요성이 있어 포스팅을 한다.
먼저 @Builder는 빌더 패턴을 사용하여 객체 생성을 할수 있게 도와주는 어노테이션이다. 문제는 해당 어노테이션이 클래스의 생성자 유무에 따라 동작을 다르게 하는데 있다.
위 내용은 Lombok의 공식문서의 @Builder의 생성자에 관한 내용이다.
Finally, applying @Builder to a class is as if you added @AllArgsConstructor(access = AccessLevel.PACKAGE)
to the class and applied the @Builder annotation to this all-args-constructor.
This only works if you haven't written any explicit constructors yourself.
If you do have an explicit constructor, put the @Builder annotation on the constructor instead of on the class.
해당 내용에 따르면 "@Builder 사용 시 생성자를 명시하지 않으면 @AllArgsConstructor(access = AccessLevel.PACKAGE)를 묵시적으로 적용한다."
이 말은 반대로 "생성자를 명시하면 @Builder는 @AllArgsConstructor를 반드시 명시해야한다는 것이다."
문제는 이 어노테이션이 주로 @Entity 클래스와 같이 사용된다는 것이다.
JPA 구현스펙에 따르면 "@Entity 클래스는 반드시 기본 생성자가 필요하다."
자바의 경우 생성자를 선언해주지 않으면 묵시적으로 기본 생성자를 만들어 주기 때문에 @Entity 클래스는 필드의 선언만으로도 클래스를 만들 수 있다.
하지만 "@Entity와 @Builder와 같이 사용한다면 과정이 훨씬 복잡해진다."
1. @Builder로 인해 묵시적으로 @AllArgsConstructor이 생성
2. @AllArgsConstructor는 자바가 묵시적으로 만들어주는 기본 생성자 생성을 막는다.
3. 하지만 @Entity는 기본 생성자가 필요하기 때문에 @NoArgsConstructor를 사용한다.
4. @Builder는 생성자를 명시할 경우 @AllArgsConstructor을 같이 명시해줘야한다.
5. 따라서 @Entity는 @Builder 사용시 @AllArgsConstructor, @NoArgsConstructor 같이 명시해줘야 한다.
개인적으로 이렇게까지 하면서 엔티티에 굳이 빌더 패턴을 적용하려 하는지 이해가 안 된다.
웹개발 단톡방에 어노테이션을 극혐하시는 분이 있는데 그 분의 마음을 공감하게 해주는 어노테이션이었다.
'DB > JPA' 카테고리의 다른 글
대리키 사용의 장단점 (0) | 2022.02.27 |
---|---|
MapStruct 참고 자료와 관련 이슈 (0) | 2022.02.05 |