본문 바로가기
개발/Finance-Seven 프로젝트

[Finance-Seven 프로젝트] JPA 상속 관계 매핑 사용하기

by 코코의 주인 2023. 2. 23.

 이번 프로젝트에는 상품의 종류로 [카드, 대출, 청약, 예,적금]을 사용합니다.

상품끼리 공통으로 사용하는 데이터가 있기 때문에 공통 부분을 부모 테이블로 만들고 상품별 정보를 자식 테이블로 하는 상속관계를 사용하기로 했습니다.

저는 상속관계 매핑 전략 중 엔티티를 각각의 테이블로 변환하는 조인 전략을 사용하기로 했습니다.

 

조인 전략(JOINED)

  • 자식 테이블이 부모 테이블의 PK를 본인의 PK이자 FK인 복합키로 사용함
  • 정규화가 가능함

1. Product Entity (부모 클래스)

@Entity
@AllArgsConstructor
@NoArgsConstructor
@Getter
@SuperBuilder
@Inheritance(strategy = InheritanceType.JOINED)	//Join 방식 사용
@DiscriminatorColumn(name = "DATA_TYPE")
@Table(name = "PRODUCTS")
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "PRODUCT_ID")
    private Long productId;

    @Column(name = "PRODUCT_NAME", columnDefinition = "VARCHAR(255)", nullable = false)
    private String productName;

    @Column(name = "COMPANY_NAME", columnDefinition = "VARCHAR(255)", nullable = false)
    private String companyName;

    @Column(name = "COMPANY_IMAGE", columnDefinition = "VARCHAR(1000)")
    private String companyImage;

    @Column(name = "THUMBNAIL", columnDefinition = "VARCHAR(1000)")
    private String thumbnail;

    @Column(name = "PRODUCT_URL", columnDefinition = "VARCHAR(1000)")
    private String productURL;

    @Column(name = "TAGS", columnDefinition = "TEXT")
    private String tags;
}

부모 클래스의 역할을 하는 클래스입니다.

1) @Inheritance(strategy = InheritanceType.JOINED)

부모 클래스에는 상속 전략을 명시해줘야 합니다. 저는 조인 전략을 사용할 것이기 때문에 위와 같이 사용했습니다.

2) @DiscriminatorColumn(name = "DATA_TYPE")

데이터를 식별할 수 있는 구분 컬럼을 설정하는 영역입니다. DiscriminatorColumn을 설정하게 되면 위와 같이 설정한 컬럼에 데이터 타입이 입력됩니다.


2. Card Entity

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@SuperBuilder
@DiscriminatorValue("CARD")	//Data_type
@Table(name = "CARD")
public class Card extends Product {

    @Column(name = "ANNUAL_FEE")
    private Integer annualFee;

    @Column(name = "BENEFITS", columnDefinition = "TEXT")
    private String benefits;

}

1) @DiscriminatorValue()

 부모 엔티티에서 설정한 구분 컬럼에 들어갈 이름을 정하는 어노테이션입니다. 설정하지 않으면 디폴트값으로 테이블명이 들어갑니다.

2) @SuperBuilder

상속받은 클래스에서도 부모 클래스의 필드도 지정하게 하기 위해 @SuperBuilder를 사용해야 합니다.


3. Loan Entity

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@SuperBuilder
@DiscriminatorValue("LOAN")
@Table(name = "LOAN")
public class Loan extends Product {

    @Column(name = "LOW_RATE", columnDefinition = "VARCHAR(255)")
    private String lowRate;

    @Column(name = "HIGH_RATE", columnDefinition = "VARCHAR(255)")
    private String highRate;

    @Column(name = "BOUND", columnDefinition = "VARCHAR(255)")
    private String bound;

    @Column(name = "QUALIFICATION", columnDefinition = "TEXT")
    private String qualification;
}

4. Savings Entity

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@SuperBuilder
@DiscriminatorValue("SAVINGS")
@Table(name = "SAVINGS")
public class Savings extends Product {

    @Column(name = "BASIC_RATE", columnDefinition = "VARCHAR(255)", nullable = false)
    private String basicRate;

    @Column(name = "PRIME_RATE", columnDefinition = "VARCHAR(255)")
    private String primeRate;

    @Column(name = "QUALIFICATION", columnDefinition = "TEXT", nullable = false)
    private String qualification;

    @Column(name = "ABOUT_PRIMTE_RATE", columnDefinition = "TEXT", nullable = false)
    private String aboutPrimeRate;
}

5. Subscritpion Entity

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@SuperBuilder
@DiscriminatorValue("SUBSCRIPTION")
@Table(name = "SUBSCRIPTION")
public class Subscription extends Product {

    @Column(name = "HIGH_RATE", columnDefinition = "VARCHAR(255)")
    private String highRate;

    @Column(name = "ABOUT_RATE", columnDefinition = "TEXT")
    private String aboutRate;

    @Column(name = "BOUND", columnDefinition = "VARCHAR(255)")
    private Integer bound;

    @Column(name = "PURCHASE", columnDefinition = "TEXT")
    private String purchase;

    @Column(name = "QUALIFICATION", columnDefinition = "TEXT")
    private String qualification;
}

 

댓글