카테고리 없음

TIL - JPA와 @Builder 사용 시 주의할 점

gentle-tiger 2025. 2. 14. 23:44

Lombok의 @Builder 어노테이션은 객체 생성 시 필드명을 명시적으로 지정할 수 있어 가독성을 높이고 유지보수를 쉽게 만들어 자주 사용한다. 하지만 JPA(Entity 클래스)와 함께 사용할 때 몇 가지 주의해야 할 사항이 있다.

 

JPA와 @Builder 사용 시 발생하는 문제

JPA는 **리플렉션(Reflection)**을 사용하여 엔티티 객체를 생성한다. 이 과정에서 기본 생성자(NoArgsConstructor)가 반드시 필요하지만, @Builder는 기본 생성자를 자동으로 생성하지 않는다.

@Entity
@Getter
@Builder
public class Product {
    @Id
    @GeneratedValue
    private Long id;

    private String name;
}

 

@Builder는 모든 필드를 초기화하는 생성자만 생성합니다. 기본 생성자가 없기 때문에 JPA가 엔티티를 인스턴스화할 때 에러 발생 가능하다. Hibernate 같은 JPA 구현체는 내부적으로 newInstance()를 사용하여 객체를 생성하는데, 기본 생성자가 없으면 리플렉션을 통한 객체 생성이 불가능하다.

 

 

해결방법

기본 생성자를 추가하고, 불필요한 객체 생성을 방지하기 위해 PROTECTED로 접근 제한을 두어야 한다.

 

 

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 기본 생성자 추가
@AllArgsConstructor // @Builder가 사용할 전체 필드 생성자
@Builder
public class Product {
    @Id
    @GeneratedValue
    private Long id;

    private String name;
}

 

왜 PROTECTED 기본 생성자를 사용해야 할까?

JPA에서 엔티티 객체 생성을 위해 기본 생성자가 필요하지만, public으로 두면 불필요한 객체 생성을 허용하게 된다. 이를 방지하기 위해 protected로 설정하면, JPA에서 정상적으로 동작하면서도 외부에서 무분별한 인스턴스 생성을 막을 수 있다!