Table per concrete class

특징

  • 상위 클래스에 하위 클래스들을 Union으로 포함하여 가지고 있게 설정한다.
  • JPA에서 TABLE_PER_CLASS는 필수 구현사항이 아니다. 따라서 밴더마다 다를 수 있다.
  • Hibernate의 polymorphic loader engine이 쿼리의 성능 걱정을 덜어 줄 것이다.
  • 하위 클래스들이 상위 클래스에 정의한 하나의 주키를 공유한다.
  • 주키 생성 타입을 identity로 하면 안 된다. AUTO로 설정했을 때 주의할 것. 안 그러면
    Cannot use identity column key generation with <union-subclass>
    mapping. 이 에러를 만나게 될 것이다.

장점

  • 다형적인 관계를 다룰 수 있다. UNION 쿼리를 사용해서 단일 테이블을 관계 맵핑 처럼 사용할 것이다.(?? 7.3 참조)
  • 지금까지는 SQL 스키마는 전혀 상속을 위한 추가 설정이 필요하지 않았다. 정규화도 잘 되었고 추가적인 외례키를 필요도 하지도 않았다.

맵핑하기

  • 상위 클래스
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BillingDetails {

@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)
@Column(name = "BILLING_DETAILS_ID")
private Long id = null;

@Column(name = "OWNER", nullable = false)
private String owner;
  • 하위 클래스
@Entity
@Table(name="CREDIT_CARD")
public class CreditCard extends BillingDetails {

@Column(name = "NUMBER", nullable = false)
private String number;

쿼리 분석

select BILLING_DETAILS_ID, OWNER, ACCOUNT, NUMBER, clazz_
from
( select OWNER, ACCOUNT, null as NUMBER, BILLING_DETAILS_ID, 1 as clazz_ from BANK_ACCOUNT
union
select OWNER, null as ACCOUNT, NUMBER, BILLING_DETAILS_ID, 2 as clazz_ from CREDIT_CARD )
  • clazz_ 컬럼: 컬렉션에서 하위 타입의 객체를 만들 때 구분하기 위해서 사용.
  • null 인 컬럼들(BANK_ACCOUNT의 NUMBER, CREDIT_CARD의 ACCOUNT): UNION을 사용하기 위해서는 같은 컬럼을 가지고 있어야 한다.