티스토리 뷰

반응형

예전 프로젝트 리팩토링을 진행하다가 문득 궁금한 것들이 생겼다.

JPA를 사용하면서 Entity, DTO 클래스에 꼭 여러가지 lombok 어노테이션을 달아왔었다.

예를 들어, @Builder, @NoArgsConstructor, @AllArgsConstructor, @Getter 등...

 

그런데 어느 순간부터 이 어노테이션이 왜 필요한지 어떻게 쓰이는지를 잊고 습관적으로 갖다 붙이고 있는 것 같았다.

알아도 정확히 알고 있는 듯한 느낌이 아니었다.

그래서 이에 대해 많이 검색해보고 알아보았다.

 

 

일단 Entity 클래스에는 @Entity 를 붙여야한다.

난 항상 이렇게 달아왔다.

@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    //....
}

 

이런 어노테이션들이 왜 필요한지 궁금해졌다.

 

엔티티에 기본 생성자를 생성해주는 @NoArgsConstructor 가 필요한 이유가 무엇일까 ?

 

JPA는 내부 로직 상 기본 생성자가 무조건 필요하다.

그래서 사실 @Entity만 작성해도 이 어노테이션 자체적으로 내부에서 기본 생성자를 생성해준다.

그 말은 즉슨 사실은 @Entity만 써도 무방하다는 것이다.

 

그런데 만약 기본 생성자에 접근 제한을 걸어서 안전성을 높이고 싶다면 @NoArgsConstructor를 직접 명시하기도 한다.

위에도 그런 예시인데, 접근 제한을 protected로 걸었다.

참고로 JPA에서 기본 생성자는 최대 접근 제한이 protected이다. (public, protected 만 가능)

 

 

그런데 왜 JPA는 기본 생성자가 private이면 안되는 것일까?

 

이유는 프록시 객체를 생성할 때 private일 경우 오류가 나기 때문이다.

즉, 즉시 로딩(EAGER)일 경우에는 실제 엔티티 객체를 조회하기 때문에 상관이 없으나,

지연 로딩(LAZY)일 경우에는 프록시 객체를 생성해야하기 때문에 private이면 오류가 나게 된다.

이에 대한 자세한 설명과 예시는 이 블로그를 참고하면 좋을 것 같다. (https://erjuer.tistory.com/106)

 

 

 

다음에는 @Builder에 대해서 알아보려한다.

빌더 패턴은 자주 사용하는데, 일관성이 깨질 위험 때문에 new()로 객체를 생성하는 것은 좋지 않기 때문이다.

그런데, @Builder는 전체 필드에 대한 값을 요구하기 때문에 전체 필드 생성자가 필요하게 된다.

그래서 항상 @AllArgsConstructor를 선언해왔다.

그런데 알고보니? @Builder에서는 자체적으로 해당 클래스에 생성자가 없다면, 전체 필드 생성자를 생성해준다는 것을 알게되었다.

 

 

그렇다면 @Builder가 전체 필드 생성자를 만들어주니까
@AllArgsConstructor를 따로 선언해주지 않아도 되는거 아닐까?

 

아니다! 위에서도 말했듯이, 클래스에 생성자가 없어야만 전체 필드 생성자를 생성해준다.

즉, 이미 기본 생성자가 있으면, 생성자가 이미 있다고 생각하여 전체 필드 생성자를 만들지 않고 이미 있는 그 생성자를 사용한다.

그런데 Builder는 전체 필드에 대한 값을 요구하기 때문에 오류가 발생하게 된다.

 

그렇기에 @NoArgsConstructor를 선언했든, @Entity가 있든 간에 기본 생성자가 생성될 것이기 때문에 

Builder는 이미 생성자가 있다고 생각하여, 전체 필드 생성자를 만들지 않을 것이다.

 

그래서 그냥 Entity 클래스에는 @NoArgsConstructor와 @AllArgsConstructor를 모두 선언하는 것이 편할듯하다.

 

 

 

이렇게 lombok이나 JPA 어노테이션들의 내부 동작이나 필요성에 대해 알아보았다.

무엇이든지 어떤 용도인지, 왜 써야하는지를 알고 사용해야한다는 것을 다시 한번 느꼈다.

반응형
댓글
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday