이 글은 김영한님의 JPA 강의 중 7장 고급 매핑을 듣고 정리한 내용입니다 :)
강의 : 자바 ORM 표준 JPA 프로그래밍 - 기본편
교재 : 자바 ORM 표준 JPA 프로그래밍🤷♀️
상속관계는 매핑을 어떻게 하나?
: JPA는 객체의 상속과 DB의 슈퍼/서브 타입 관계를 매핑해준다
(관계형 DB에는 상속관계가 없음, 그나마 슈퍼-서브 타입이 객체의 상속과 유사함!)
이 상속관계 매핑에는 3가지 방법이 있는데,
보통은 1번을 사용, 설계가 단순한 경우는 2번을 사용하기도 한다. 그리고 3번은 절대 쓰지 말자-!
- 조인 (기본적으로 사용)
- 단일 테이블 (정말 단순한 설계일 경우 사용)
- 클래스마다 각각 테이블로 만들기 (사용X)
이 3가지의 방법은,
우선 엔티티 다 코드 짜고, 그냥 어노테이션만 변경하면 다른 방법으로 바로 바꿀수 있다.
=> 이게 JPA의 편한점이다! 전략 바뀔때마다 코드를 다 다시 짜는 게 아니라, 어노테이션만 변경하면 된다!
@Inheritance(strategy = InheritanceType.JOINED)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
1. 조인 전략 (기본)
: 각각 테이블로 만들고 슈퍼타입에 조인시킴! 기본적으로 주로 사용한다.
슈퍼타입 엔티티에 @Inheritance(strategy = InheritanceType.JOINED)
이때 슈퍼 타입에 속성으로 DTYPE을 두어서, 슈퍼타입 테이블만 보고도 어떤 서브타입인지 구분함 (사실 이 전략에서는 없어도 가능함, 2번에서는 필수)
- 장점 : 상속 기능 활용(자식 클래스들의 전체 price를 구할때라던지), 외래키 참조할 때도 부모의 PK만 찾으면 OK, 저장 공간 효율화
- 단점 : 조회 시 조인 많이 사용, 쿼리 2번 호출 ⇒ 근데 이것들은 큰 문제는 아님

// 슈퍼 타입 엔티티
@Entity
@Inheritance(strategy = InheritanceType.JOINED) //첫번째 전략!
@DiscriminatorColumn // 기본이름은 DTYPE
public class Item
{
@Id @GeneratedValue
private Long id;
private String name;
}
// 서브 타입 엔티티 중 Album
@Entity
@DiscriminatorValue // 기본은 엔티티 이름 (여기서는 Album)
public class Album extends Item
{
private String artist;
}
2. 단일 테이블
: 모든 속성을 하나의 테이블에 몰아넣기, 정말 단순한 설계일 경우 사용한다.
슈퍼타입 엔티티에 @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
여기서는 슈퍼 타입에 속성으로 DTYP을 꼭 설정해주어야 함! (그래야 구분 가능)
- 장점 : 성능이 잘 나오고, 쿼리가 한번에, 조인할 필요 없음
- 단점 : 속성들이 다 null이 허용되어야하고, 오히려 성능이 느려질 수 있음 (보통은 성능이 느려질정도까지는 아니긴하나 참고)

// 슈퍼 타입 엔티티
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) //두 번째 전략!
@DiscriminatorColumn
public class Item
{
@Id @GeneratedValue
private Long id;
private String name;
}
3. 클래스마다 각각 테이블로 만들기
: 상속도 아니고 그냥 서브타입들을 단일 테이블로 만듦. 이건 그냥 쓰지 말것
- 장점 : 생성은 쉬움
- 단점 : 상속의 장점을 전혀 못 사용함 (price 전체 구하는 거 못함)
부모클래스에서 조회를 못하니까, PK로 조회시 모든 자식 테이블들을 다 찾아봐야함!

// 슈퍼 타입 엔티티
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) //두 번째 전략!
// @DiscriminatorColumn 이 어노테이션은 필요없음
public abstract class Item
{
@Id @GeneratedValue
private Long id;
private String name;
}
❔ @MappedSuperclass 란
: 객체 만들때 반복되는 몇가지 속성을 저장해두고 필요할때마다 사용하기 위한 어노테이션! (매핑 정보만 상속하는 슈퍼클래스라고 생각하자)
- 언제 사용하나 ? ⇒ 상속관계는 아니지만 몇가지 속성만 같이 쓰고 싶을때 사용하자
- 상속관계 매핑 X, 엔티티 X, DB 테이블에 매핑 X(조회, 검색 안 됨)
- 직접 생성할 일 없으므로 추상 클래스로 만들자

// 속성만 상속하는 슈퍼클래스
@MappedSuperclass
public abstract class BaseEntity // 엔티티 아님!
{
private String createdBy;
private LocalDateTime createdDate;
}
@Entity
public class Member extends BaseEntity {
...
}'Back-end > JPA' 카테고리의 다른 글
| [JPA/김영한] 영속성 전이, 고아객체 (0) | 2022.06.23 |
|---|---|
| [JPA/김영한] 프록시와 지연로딩 (0) | 2022.06.23 |
| [JPA/김영한] 여러가지 연관관계 매핑 (0) | 2022.06.23 |
| [JPA/김영한] 연관관계 매핑하기 (0) | 2022.06.23 |
| [JPA/김영한] 엔티티 매핑 (0) | 2022.06.23 |