[SpringBoot3] 엔티티 상속관계에서 @Builder 적용

2024. 3. 20. 22:16·Framework/SpringBoot
상속관계에서 Builder를 적용했을 때 발생한 이슈에 대해 작성한 글입니다.

발생 배경

엔티티에 @Builder 어노테이션을 사용하였습니다.

@Entity
@DiscriminatorValue("PRODUCT")
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Product extends Item {

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private ProductStatus status;

    // ...
}

 

다만 Product의 부모 엔티티인 Item에도 @Builder 어노테이션이 있는데요

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dtype", discriminatorType = DiscriminatorType.STRING)
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Item {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(targetEntity = User.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;
    
    // ..
}


이 때 아래와 같은 에러가 발생했습니다.

error: builder() in Product cannot hide builder() in Item
@Builder
^
  return type ProductBuilder is not compatible with ItemBuilder

 

문제

 

에러 메세지를 보면 유추할 수 있듯이, 이 에러는 상속 관계의 엔티티에서 빌더를 잘 못 사용하여 발생한 에러입니다.

 

@Builder 어노테이션을 사용하여 초기화할 때, 자식 클래스에서 부모 클래스의 필드를 발견하지 못하며 따라 자식 클래스를 초기화 할 때 부모 클래스의 필드를 초기화 할 수 없어 발생하는 에러입니다.

 

해결

이 문제를 @SuperBuilder 어노테이션을 통해 해결할 수 있습니다.@SuperBuilder를 사용하면 자식 클래스에서 빌더를 생성할 때 부모 클래스의 필드와 메서드가 자동으로 포함됩니다. 따라 부모의 클래스를 초기화할 수 있게 됩니다.

 

@SuperBuilder 어노테이션을 사용하여 코드를 수정했습니다.

 

Product.java

@Entity
@DiscriminatorValue("PRODUCT")
@Getter
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Product extends Item {

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private ProductStatus status;

    // ...
}

 

Item.java

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dtype", discriminatorType = DiscriminatorType.STRING)
@Getter
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Item {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(targetEntity = User.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;
    
    // ..
}

 

 

'Framework > SpringBoot' 카테고리의 다른 글

[Spring] VO와 BO, DAO, DTO란 무엇인가  (1) 2024.03.24
[SpringBoot3] 스프링부트와 Swagger 연결방법  (0) 2024.03.21
[SpringBoot] application.properties에서 DB 정보 등 민감한 내용 분리하기  (0) 2024.03.13
[Spring] MappedSuperclass 사용하기  (0) 2024.02.14
[SpringBoot] 데이터베이스 스키마 자동 생성 옵션에 대해 알아보자 / spring.jpa.hibernate.ddl-auto  (0) 2023.12.26
'Framework/SpringBoot' 카테고리의 다른 글
  • [Spring] VO와 BO, DAO, DTO란 무엇인가
  • [SpringBoot3] 스프링부트와 Swagger 연결방법
  • [SpringBoot] application.properties에서 DB 정보 등 민감한 내용 분리하기
  • [Spring] MappedSuperclass 사용하기
hurlud
hurlud
나와 같은 궁금증을 가진 사람들을 위해 오늘도! 🐥
  • hurlud
    주독야독
    hurlud
  • 전체
    오늘
    어제
  • 최근 글

    • ALL (106)
      • CS (13)
      • Linux (2)
      • Deploy (7)
        • AWS (6)
        • Docker (1)
      • IDE (13)
        • IntelliJ (5)
        • Android Studio (8)
      • DB (10)
        • MySQL (6)
        • MongoDB (4)
      • Programming Language (20)
        • JavaScript (10)
        • Java (8)
        • Python (2)
      • Framework (32)
        • Node.js (6)
        • SpringBoot (17)
        • React (6)
        • NestJS (2)
      • Git | Github (4)
      • ETC (5)
      • Akka (0)
  • 링크

    • 깃허브
  • hELLO· Designed By정상우.v4.10.0
hurlud
[SpringBoot3] 엔티티 상속관계에서 @Builder 적용
상단으로

티스토리툴바