포스트

자바 ORM 표준 JPA2

자바 ORM 표준 JPA 프로그래밍2

김영한 지음

JPA 에서 교과서로 유명한 책을 읽고 일부 부분을 메모해봤습니다.

7장 고급 매핑

상속 관계 매핑

관계형 데이터베이스에서 객체의 상속 개념을 나타내기 위해서는 어떻게 해야 할까? 이를 해결하기 위한 방법은 3가지가 있다.

  • 각각의 테이블로 변환 : 각각 모두 테이블로 만들고 조회할 때 join 을 사용하는 방법
  • 통합 테이블로 변환 : 테이블을 통합해서 사용하는 방법
  • 서브타입 테이블로 변환 : 서브 타입마다 하나의 테이블을 만드는 방법

조인 정략

자식 테이블이 부모 테이블의 기본 키를 받아서, 기본 키 + 외래 키로 사용하는 전략이다. 타입을 구분하는 컬럼을 추가해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item {

  @Id
  @GeneratedValue
  @Column(name = "ITEM_ID")
  private Long Id;

}

@Entity
@DiscriminatorValue("A")
public class Album extends Item {

  private String artist;
}

  • Inheritance 상속 매핑은 부모 클래스에 사용해야 한다. 매핑 전략을 지정한다.
  • DiscriminatorColumn : 부모 클래스에 구분 컬럼을 지정한다. 이 컬럼으로 저장된 자식 테이블을 구분할 수 있다.
  • DiscriminatorValue : 엔티티를 저장할 때, 구분 컬럼에 입력할 값을 지정한다.

기본적으로 자식 테이블은 부모 테이블의 ID 컬럼명을 그대로 사용한다. 만약 자식 테이블의 기본 키 컬럼명을 변경하고 싶으면 @PrimaryKeyJoinColumn 을 사용하면 된다.
장단점을 비교하면 다음과 같다.
장점

  • 테이블이 정규화된다.
  • 외래 키 참조 무결성 제약조건을 활용할 수 있다.
  • 저장공간을 효율적으로 사용한다.

단점

  • 조회할 때 조인이 많이 사용되므로 성능이 저하된다.
  • 조회 쿼리가 복잡하다.
  • 데이터를 등록할 Insert SQL 을 두 번 실행한다.

단일 테이블 전략

단일 테이블 전략은 테이블을 하나만 사용한다. 구분 컬럼으로 어떤 자식 데이터가 저장되었는지 구분한다.
장점

  • 조인이 필요 없으므로 일반적으로 조회 성능이 빠르다.
  • 조회 쿼리가 단순하다.

단점

  • 자식 엔티티가 매핑한 컬럼은 모두 null 을 허용해야 한다.
  • 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다. 상황에 따라서는 조회 성능이 오히려 느려진다.

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

자식 엔티티마다 테이블을 만든다. 자식 테이블에는 각각에 필요한 컬럼이 모두 있다.
장점

  • 서브 타입을 구분해서 처리할 때 효과적이다.
  • not null 제약 조건을 사용할 수 있다.

단점

  • 여러 자식 테이블을 함께 조회할 때 성능이 느리다.
  • 자식 테이블을 통합해서 쿼리하기 어렵다.


이 전략은 데이터베이스 설계자와 ORM 전문가 둘 다 추천하지 않는 전략이다. 조인이나 단일 테이블 전략을 고려하자.

MappedSuperclass

상속 관계 매핑은 부모 클래스와 자식 클래스를 모두 DB 테이블과 매핑했다. 부모 클래스는 테이블과 매핑하지 않고 부모 클래스를 상속 받는 자식 클래스에게 매핑 정보만 제공하고 싶으면 @MappedSuperclass 를 사용하면 된다.

  • 테이블과 매핑되지 않고 자식 클래스에 엔티티의 매핑 정보를 상속하기 위해 사용한다.
  • @MappedSuperclass 로 지정한 클래스는 엔티티가 아니므로 em.find() 나 JPQL 에서 사용할 수 없다.
  • 이 클래스르 직접 생성해서 사용할 일은 거의 없으므로 추상 클래스로 만드는 것을 권장한다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.