상속관계 매핑 - @Inheritance
관계형 DB는 상속 관계라는 개념이 없고, 슈퍼 타입, 서브 타입 관계라는 모델링 기법이 객체 상속과 유사하다.
그래서 JPA는 객체의 상속 구조와 DB의 슈퍼타입 서브타입 관계를 매핑할 수 있는 상속 관계 매핑을 지원한다.
JPA의 상속 관계 매핑은 총 3가지 방법이 존재한다.
- JOIN 전략 ( JOINED )
- 단일 테이블 전략 ( SINGLE_TABLE )
- 구현 클래스마다 테이블 전략 ( TABLE_PER_CLASS ) - 많은 단점이 존재해 추천 X
상속 관계 매핑에 사용되는 주요 어노테이션은 다음과 같다.
@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;
...
}
'◼ JAVA > JPA' 카테고리의 다른 글
[JPA] Entitiy에서 왜 Setter를 사용하지 말라고 할까? (0) | 2023.06.08 |
---|---|
[JPA] 영속성 전이(cascade)와 고아객체(orphalRemoval)란? (0) | 2023.06.07 |
[JPA] 연관관계 매핑 총 정리 (0) | 2023.06.06 |
[JPA] 연관관계 매핑 주인에 대해서 (mappedBy) (0) | 2023.06.06 |
[JPA] 기본 키 매핑 (기본키 자동 생성 전략) (0) | 2023.06.05 |