본문 바로가기

BackEnd/JPA

[JPA] 상속관계 매핑 전략(@Inheritance, @DiscriminatorColumn)

상속관계 매핑

  • 관계형 데이터베이스는 상속관계가 없다.
  • 슈퍼타입 서브타입 관계라는 모델링 기법이 객체의 상속과 유사하다.
  • 슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법
    - 각각 테이블로 변환 → 조인 전략
    - 통합 테이블로 변환 → 단일 테이블 전략
    - 서브타입 테이블로 변환 → 구현 클래스마다 테이블 전략 (구조적 결함이 커 실무에서 미사용)

 주요 어노테이션

  • @Inheritance(strategy=InheritanceType.XXX)
    - JOINED : 조인 전략
    - SINGLE_TABLE : 단일 테이블 전략
    - TABLE_PER_CLASS : 구현 클래스마다 테이블 전략 (실무 미사용)
  • @DiscriminatorColumn(name="DTYPE")
    : 하위 클래스를 구분하는 용도의 컬럼이며 기본 값은 "DTYPE"이다.  부모 클래스에 선언한다.
  • @DiscriminatorValue("XXX")
    : 엔티티를 저장할 때 슈퍼타입의 구분 컬럼(DTYPE)에 저장할 값을 지정할 수 있다.
    하위 클래스에 선언하며 선언을 안했을 경우 클래스 이름으로 구분 컬럼에 저장이 된다.

 조인전략

  • 장점은 테이블을 정규화이며 외래 키 참조 무결성 제약조건을 활용 가능하다. 
    또한 저장공간을 효율적으로 사용한다.
  • 단점은 조회 시조인을 많이 사용해 성능 저하가 올 수 있으며 쿼리가 복잡하다. 
    데이터 저장 시 INSERT SQL을 2번 호출해야 한다.
  • 하지만 단점보다는 장점이 극대화 되므로 기본전략은 조인전략을 선호한다.

김영한의 자바 ORM 표준 JPA 프로그래밍

 

@Entity
@Inheritance(strategy = InteritanceType.JOINED)   // 전략설정
@DiscriminatorColumn                              // 하위 테이블을 구분할 컬럼을 생성하기 위함
public class Item {
    @Id @GeneratedValue
    @column(name = "item_id")
    private Long id;
    private String name;
}
@Entity
public class Movie extends Item {
    private String director;
    private String actor;
}
@Entity
public class Book extends Item {
    private String acthor;
    private String isbn;
}
@Entity
public class Album extends Item {
    private String artist;
}

 

 단일 테이블 전략

  • 장점은 조인이 필요 없으므로 일반적으로 조회 성능이 빠르며 조회 쿼리가 단순하다.
  • 단점은 자식 엔티티가 매핑한 컬럼은 모두 null을 허용해야 한다.  그리고 단일 테이블에 모든 것을 저장하므로
    테이블이 커질 수 있어 상황에 따라서 조회 성능이 느려질 수 도 있다.
  • 단일 테이블 전략의 경우 @DiscriminatorColumn 어노테이션을 선언하지 않아도 기본으로 DTYPE 컬럼이 생성된다.
    왜냐하면, 한 테이블에 모든 객체정보를 저장하기 때문에 DTYPE 없이는 어떤 테이블인지 판단할 수 없기 때문이다.
  • 비지니스가 단순할 경우 단일 테이블 전략이 개발에 수월하다.

김영한의 자바 ORM 표준 JPA 프로그래밍

 

@Entity
@Inheritance(strategy = InteritanceType.SINGLE_TABLE)
@DiscriminatorColumn  // 생략 하더라도 단일 테이블의 경우 DTYPE 컬럼이 테이블에 강제로 생성된다.
public class Item {
    @Id @GeneratedValue
    @column(name = "item_id")
    private Long id;
    private String name;
}
@Entity
public class Movie extends Item {
	private String director;
    private String actor;
}
@Entity
public class Book extends Item {
	private String acthor;
    private String isbn;
}
@Entity
public class Album extends Item {
	private String artist;
}

 

 구현 클래스마다 테이블 전략

  • 이 전략은 DBA, ORM 전문가 둘다 추천하지 않는다. (실무미사용)
  • 장점은 서브 타입을 명확하게 구분해서 처리할 때 효과적이며 not null 제약조건을 사용할 수 있다.
  • 단점은 자식 테이블들을 함께 조회할 때 성능이 느리며 쿼리를 작성하기 번거롭다.(UNION SQL사용)
  • @DiscriminatorColumn 어노테이션은 해당 전략에서는 의미가 없다.

김영한의 자바 ORM 표준 JPA 프로그래밍

 

@Entity
@Inheritance(strategy = InteritanceType.TABLE_PER_CLASS)
public abstract class Item {
    @Id @GeneratedValue
    @column(name = "item_id")
    private Long id;
    private String name;
}
@Entity
public class Movie extends Item {
	private String director;
    private String actor;
}
@Entity
public class Book extends Item {
	private String acthor;
    private String isbn;
}
@Entity
public class Album extends Item {
	private String artist;
}

 

'BackEnd > JPA' 카테고리의 다른 글

[JPA] 고급매핑 (상속관계, @MappedSuperclass)  (0) 2024.04.18
[JPA] 프록시와 연관관계 관리  (0) 2024.02.27
[JPA] 연관관계 매핑  (0) 2024.02.21
[JPA] 연관관계 매핑 기초  (0) 2024.02.20
[JPA] 엔티티 매핑  (0) 2024.02.13