JPA의 @Inheritance 필요성
- 자바에서는 상속관계가 존재하지만, DB에선 존재하지 않음, 그나마 유사한 슈퍼 타입 - 서브 타입의 관계 정도 존재하지만 실질적인 상속관계가 아님.
- 즉 자바에서의 상속관계를 DB에 어떻게 매핑할 것인가를 JPA는
@Inheritiance를 통해 정의할 수 있음
- 총 3가지 방식으로 DB에 매핑시킬 수 있음
1. 단일 테이블(SINGLE_TABLE) 전략
- 부모 - 자식 관계에서 부모 테이블에 모든 자식의 칼럼들을 전부 정의하는 방식임
- 이에 따라 한 테이블로 모든 것이 표현됨
- 부모 엔티티에
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 를 지정함으로써 가능
- 즉 한 테이블에 모든 자식들에 대한 값들을 전부 표현하는 거니 특정 자식에 대한 칼럼만 할당한다면 나머지 자식의 칼럼들은 NULL이 됨
- 즉 자식 테이블 중 하나라도 NOT NULL이면 안 됨 , NOT NULL이면 다른 자식 테이블 칼럼에 값을 넣을 때 값이 NULL로 들어가므로 오류 발생
- 즉 여러 필드에 NOT NULL을 지정해야한다면, 단일 테이블보단 다음에서 소개할 조인 전략을 채택할 것을 권고
2. 조인(JOINED) 전략
- 말 그대로 참조 시 조인을 통해 조회할 수 있게끔 JPA가 해주는 전략임
- 즉 자바의 상속관계와 가장 흡사한 슈퍼타입 - 서브타입으로 테이블을 매핑
- 공통 칼럼들을 부모 테이블에 몰아넣고 자식 테이블에는 자식 테이블 고유의 칼럼들만 배치하여 외래키 참조를 통해 지정하는 것
조인 전략 주의
-
조인 전략 시에는 반드시 부모 테이블에 @DiscriminatorColumn 를 지정해줘야됨
-
해당 어노테이션은 부모 테이블에 DTYPE을 나타내주는 어노테이션
-
DTYPE이란 부모 테이블에 저장된 데이터가 어느 자식 테이블의 데이터인지를 식별하기 위한 식별자임, 만약 DTYPE 칼럼이 부모테이블에 없으면 부모 테이블에 존재하는 특정 데이터가 어떤 자식의 데이터인지 알 수 없게 되므로
-
예를 들어@DiscriminatorValue(value = "BOOK") 와 같이 자식 엔티티에 지정하면 부모 테이블에 DTYPE="BOOK"으로 저장되고 해당 row는 BOOK 자식 테이블의 데이터임을 식별할 수 있게 됨, DTYPE 이름은 자신이 원하는대로 커스텀 가능
-
결론 : 자바의 상속관계를 DB에 매핑할 경우 조인 전략 시 DTYPE역할을 하는 칼럼이 무조건 존재해야됨 ! , 또한 NOT NULL이면 안 됨
조인 전략 결론
- DTYPE 칼럼 피루
- NOT NULL X
3. 구현 클래스마다 테이블(TABLE_PER_CLASS) 전략
- 부모 테이블은 생성 안 하고, 각 자식 테이블들에 공통된 칼럼을 정의하는 방식
- 즉 부모가 없고 자식만 존재
- 부모 타입으로 조회 시 UNION쿼리 나감에 따라 테이블 많아지면 성능 매우 나빠져짐
- 논리적으로도 부모 없이 자식 테이블들에 정의할거면 상속관계의 논리에서 어긋남
- 즉 실무에서 잘 안 씀
어떤 전략?
간단할 경우는 단일 테이블 전략 사용하고, 자식 클래스가 많은 복잡한 상속관계일 경우는 조인 전략 사용하자.