인프런 커뮤니티 질문&답변

정기민님의 프로필 이미지

작성한 질문수

@Builder 사용 질문

작성

·

516

0

@Builder 어노테이션 사용 관련해서 질문이 있어 글을 작성하게 되었습니다.

@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class Member {

    @Id
    @GeneratedValue
    @Column(name = "member_id")
    private Long id;

    // Properties
    private String name;
}

위와 같이 @Entity 클래스 단에서 @Builder 어노테이션을 사용할 때, @NoArgsConstructor 와 @AllArgsConstructor 를 사용해야 하는 것으로 알고 있습니다. 이와 관련해서 질문을 작성하겠습니다!

  1. @Entity 와 @Builder 만 사용했을때에 에러가 발생합니다.

     

    "이는 @Entity 어노테이션을 사용했을때, 해당 클래스에 아무런 생성자가 없다면 @Entity 가 기본 생성자를 생성해줍니다." 라고 이해했는데 맞나요?

  2. 그렇다면 @Entity와 @Builder 를 사용하고, @AllArgsConstructor를 사용하면 기본 생성자는 @Entity가 만들어주었으므로, 기본 생성자를 만들어주는 역할을 하는 @NoArgsConstructor 는 필요없는 것 아닌가요?
    그런데 @NoArgsConstructor까지 사용해야 에러가 발생하지 않습니다.

  3. @Builder를 사용한 클래스에 어떠한 생성자도 없다면 클래스의 모든 필드를 매개변수로 가지는 private 생성자를 만들어주는 것이 맞나요?

  4. 이것이 맞다면 2번의 질문과 반대로, @Builder 를 사용했기 때문에 @AllArgsConstructor 가 담당하는 모든 필드에 대한 생성자가 만들어져있으므로 @NoArgsConstructor 만 사용하면 되는 것 아닌가요?
    여기에서도 @AllArgsConstructor 까지 사용해주어야 에러가 발생하지 않습니다.

질문이 좀 많은데 요약하자면, 빌더 패턴을 사용하려고 할때, @Entity, @Builder, @NoArgsConstructor, @AllArgsConstructor 이 네개의 어노테이션을 왜 꼭같이 사용해야 하는지가 궁금합니다.

 

감사합니다!

답변 1

0

안녕하세요, 인프런 AI 인턴입니다.

정기민님의 질문에 답변드립니다. @Entity@Builder 어노테이션을 사용하실 때, 생기는 질문과 그에 대한 답변은 다음과 같습니다:

  1. @Entity 어노테이션을 사용할 때, 기본 생성자가 자동으로 필요한 이유는 JPA 스펙에 따라 엔티티 클래스는 기본 생성자를 가져야 하기 때문입니다. 따라서 해당 클래스에 명시적인 생성자가 없을 경우 JPA 구현체가 기본 생성자를 생성해주는 것이 맞습니다.

  2. @AllArgsConstructor를 사용하게 되면 클래스의 모든 필드를 가지는 생성자를 생성합니다. 하지만 JPA 스펙상 엔티티는 기본 생성자도 필요하기 때문에, @NoArgsConstructor를 사용하여 기본 생성자를 명시적으로 제공해야 합니다. 이는 JPA가 엔티티 객체를 프록시로 사용하기 위해 필요합니다.

  3. @Builder를 사용할 경우, 이 어노테이션이 자동으로 해당 클래스의 모든 필드를 포함하는 생성자를 내부적으로 사용하여 빌더 클래스를 생성합니다. 그러나 이때 생성되는 생성자는 private입니다.

  4. 따라서 @NoArgsConstructor@AllArgsConstructor 모두 사용하는 이유는 @NoArgsConstructor로 인해 JPA 스펙에서 요구하는 기본 생성자를 만족시키고, @AllArgsConstructor를 통해 @Builder가 필요로 하는 모든 필드를 포함하는 생성자를 만들어주기 때문입니다. @Builder만 사용하더라도 @NoArgsConstructor는 JPA가 엔티티를 올바르게 관리하기 위해 필요합니다.

결론적으로, @Entity, @Builder, @NoArgsConstructor, @AllArgsConstructor를 함께 사용하는 것은 JPA 스펙을 준수하면서 동시에 빌더 패턴을 효율적으로 구현하기 위함입니다.

질문에 대한 답변이 되었기를 바랍니다. 감사합니다!

정기민님의 프로필 이미지
정기민
질문자

@Entity 어노테이션을 사용할 때, 기본 생성자를 JPA 구현체가 자동으로 생성해준다고 하셨습니다.

그런데, 2번 질문의 답에서 엔티티는 기본 생성자도 필요하기 때문에, @NoArgsConstructor 를 사용하여 기본 생성자를 명시적으로 제공해야 합니다. 라고 하셨습니다. 여기에서는 왜 JPA 구현체가 기본 생성자를 자동으로 생성해주지 않는 것 인가요? 이미 @AllArgsConstructor 를 사용하기 때문에 추가적으로 생성자를 만들어주지 않는 것 인가요?

넵 생성자가 이미 존재하는 경우에는 디폴트 생성자가 생성되지 않습니다!