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을 사용하기 위해서는 같은 컬럼을 가지고 있어야 한다.