본문 바로가기
[Spring Boot]/[JPA]

[JPA] 상속관계 매핑

by 북방바다코끼리표범 2023. 10. 26.

복습

https://shins99.tistory.com/114

 

[JPA] 연관관계 매핑 정리

복습 https://shins99.tistory.com/113 [JPA] 양방향과 단방향 매핑, 연관관계의 주인(mappedBy) 복습 http://shins99.tistory.com/112 [JPA] 기본 키(primary key)와 매핑 복습 https://shins99.tistory.com/111 [Spring Boot] 페이징(paging

shins99.tistory.com


상속관계 매핑 - @Inheritance

- 관계형 DB는 상속 관계라는 개념이 없고, 슈퍼 타입, 서브 타입 관계라는 모델링 기법이 객체 상속과 유사

- JPA는 객체의 상속 구조와 DB의 슈퍼타입 서브타입 관계를 매핑할 수 있는 상속 관계 매핑을 지원

 

JPA의 상속 관계 매핑 방법

  • JOIN 전략 (JOINED)
  • 단일 테이블 전략 (SINGLE_TABLE)
  • 구현 클래스마다 테이블 전략 ( TABLE_PER_CLASS ) - 추천하지 않음

 

상속 관계 매핑에 사용되는 주요 어노테이션

@Inheritance(strategy=InheritanceType.??)

- 상속관계 매핑을 사용하는 주요 어노테이션으로 부모클래스에 해당 어노테이션을 붙임

- ?? 에 사용하고자 하는 상속 전략을 넣어주면 됨

 

@DiscriminatorColumn

- 슈퍼타입 테이블에 있는 정보가 어느 서브타입의 정보인지를 알려주는 컬럼을 만들어주는 어노테이션

- 기본값은  DTYPE

- name 속성 값으로 이름 변경 가능

 

주의할점

- 조인 전략에서 자식 엔티티를 구분하기 위해 @DiscriminatorColumn을 꼭 선언해야 함

(자식 엔티티와 관련된 정보를 조회할 때 부모 엔티티와 연관된 정보를 참조할 수 있기 때문)

 

- 단일테이블 전략은 @DiscriminatorColumn를 선언하지않아도 자동생성 가능

(단일이기 때문에 구분이 없으면 어느정보인지 구별할 수 없기 때문)


JOINED 전략

- 각각의 엔티티를 별도의 테이블로 생성

공통 속성을 가진 엔티티는 부모 테이블을 생성하고 자식 테이블에서는 자신만의 속성을 추가하는 방식으로 구현

 

 
@Entity
 
@Inheritance(strategy = InheritanceType.JOINED)
 
@DiscriminatorColumn
 
public class Item {
 
 
 
@Id @GeneratedValue
 
private Long id;
 
 
 
private String name;
 
private int price;
 
...
 
}

 
@Entity
 
public class Movie extends Item {
 
private String director;
 
private String actor;
 
...
 
}

 

장점 단점
테이블이 정규화 되어 있다. 조회시 조인을 많이 사용해야 해서 성능 저하가 있다.
필요없는 데이터를 저장하지 않아 저장공간을 효율적으로 사용할 수 있다. 데이터 저장시 INSERT SQL 2번씩 호출한다.

 

주의할점

- JOINED 전략은 @DiscriminatorColumn을 꼭 선언해야 함

(아래처럼 부모 테이블에 어떤 자식 테이블이 들어 왔는지 구분 가능)


SINGLE_TABLE 전략

- 상속 구조의 모든 클래스 정보를 하나의 테이블에 저장하는 전략

- 부모 클래스와 자식 클래스 간에 공통 속성뿐만 아니라 자식 클래스만의 속성도 함께 저장됨

 

구현 방법:  JOINED과 동일. 전략만 SINGLE_TABLE로 변경

 
@Entity
 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
 
@DiscriminatorColumn
 
public class Item {
 
 
 
@Id @GeneratedValue
 
private Long id;
 
 
 
private String name;
 
private int price;
 
...
 
}

 
@Entity
 
public class Movie extends Item {
 
private String director;
 
private String actor;
 
...
 
}

 

장점 단점
하나의 테이블에 저장되기 때문에 조인이 필요 없으므로 일반적으로 조회 성능이 빠르다. 자식 엔티티가 매핑한 컬럼은 모두 null 허용한다.
테이블 구조가 단순하고 관리하기 쉽다. 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다.
상황에 따라서 조회 성능이 오히려 느려질 수 있다.
INSERT 시 쿼리가 1번만 나간다. 중복 문제가 발생할 가능성이 있다.

매핑 정보 상속 - @MappedSuperclass

- 여러 엔티티가 공통으로 사용하는 정보를 제공하기 위해 사용 ( 상속 관계 매핑 X )

- 테이블과 직접 매핑되지 않음

- @MappedSuperclass 어노테이션이 붙은 클래스를 상속받는 자식 클래스에게 매핑 정보만을 제공

 

- 직접 생성해서 사용할 일 이 없음

(추상 클래스 (abstract)로 생성하는 것을 권장, 테이블이 생성되지 않으므로 조회나 검색이 불가능)

사용방법

- 여러 엔티티가 공통으로 갖는 정보가 있는 클래스에 @MappedSuperclass 어노테이션을 붙임

- 클래스를 상속 받는 엔티티는 이 클래스의 정보가 컬럼으로 생성됨

 

 
@MappedSuperclass
 
public abstract class BaseEntity {
 
private LocalDateTime createdDate;
 
 
 
private LocalDateTime lastModifiedDate;
 
}

 
@Entity
 
public class Item extends BaseEntity{
 
 
 
@Id
 
@GeneratedValue
 
private Long id;
 
 
 
private String name;
 
private int price;
 
...
 
}