JPA 상속관계 매핑

유기훈·2025년 3월 6일

단일 테이블 전략

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)

  • 하나의 테이블에 모든 엔티티 정보를 저장하는 방식.
  • @DiscriminatorColumn을 사용해서 어떤 서브클래스인지 구분하는 DTYPE 컬럼을 추가할 수 있음.

장점

  • 조인이 필요 없어서 조회 성능이 빠름.
  • 구현이 단순함.

단점

  • 불필요한 컬럼이 많아짐 (NULL이 자주 발생).
  • 서브타입이 많아지면 테이블이 비대해질 위험이 있음.
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Employee {
    @Id @GeneratedValue
    private Long id;
    private String name;
}

@Entity
@DiscriminatorValue("FullTimeEmployee")
public class FullTimeEmployee extends Employee {
    private int salary;
}

@Entity
@DiscriminatorValue("PartTimeEmployee")
public class PartTimeEmployee extends Employee {
    private int hourlyRate;
}

조인 전략

@Inheritance(strategy = InheritanceType.JOINED)

  • 부모 테이블과 자식 테이블을 따로 생성하고, PK를 공유하는 방식.
  • @PrimaryKeyJoinColumn을 사용하여 자식 테이블의 PK를 부모 테이블의 FK로 설정.
  • 부모 테이블과 조인해서 데이터를 가져와야 함.

장점

  • 데이터 정규화가 잘 되어 테이블이 깔끔함.
  • NULL 값이 없어서 공간 낭비가 없음.

단점

  • 조회 시 JOIN이 필요해서 성능이 다소 저하될 수 있음.
  • INSERT가 여러 테이블에 발생해서 성능이 저하될 수 있음.
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Employee {
    @Id @GeneratedValue
    private Long id;
    private String name;
}

@Entity
@PrimaryKeyJoinColumn(name = "EMPLOYEE_ID")
public class FullTimeEmployee extends Employee {
    private int salary;
}

@Entity
@PrimaryKeyJoinColumn(name = "EMPLOYEE_ID")
public class PartTimeEmployee extends Employee {
    private int hourlyRate;
}

Mapped Superclass 전략

  • 부모 클래스를 엔티티가 아닌, 단순히 공통 필드를 상속하는 용도로 사용.
  • 부모 테이블을 따로 만들지 않고, 자식 테이블에 필드만 추가됨.
  • JPA에서 조회할 때 부모 타입으로 조회할 수 없음.

장점

  • 공통 필드를 쉽게 관리 가능 (createdAt, updatedAt 같은 공통 필드 관리할 때 유용).
  • 불필요한 부모 테이블이 생기지 않음.

단점

  • 부모 클래스로 조회 불가능 (@Entity가 아니라서).
  • 상속받은 엔티티마다 중복된 컬럼을 가지게 됨.
@MappedSuperclass
public abstract class BaseEntity {
    private String name;
}

@Entity
public class FullTimeEmployee extends BaseEntity {
    @Id @GeneratedValue
    private Long id;
    private int salary;
}

@Entity
public class PartTimeEmployee extends BaseEntity {
    @Id @GeneratedValue
    private Long id;
    private int hourlyRate;
}
profile
개발 블로그

0개의 댓글