[JPA] JPA 상속관계 매핑(@Inhertinace)

2024. 11. 18. 09:38·Programming/Spring,JPA

JPA 상속관계 매핑

JPA 상속 관계 매핑이란, 객체지향 언어의 상속 개념을 데이터베이스 관계형 모델에 맞게 구현하는 기능이다.

JPA는 객체 모델에서 상속 구조를 데이터베이스에 적절하게 매핑하기 위해 세 가지 전략을 제공한다.

  1. Joined Table
  2. Single Table
  3. Table per Class

JPA에서 상속을 매핑할 때는 상위 클래스에 @Inheritance 어노테이션을 추가해 사용하며, 상속 전략을 지정할 수 있다.

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Product {
	@Id @GeneratedValue
	private Long id;
	private int price;
}

 

1. Joined Table 전략

Joined Table 전략은 상위 클래스와 각 하위 클래스마다 별도의 테이블을 생성하고, 하위 클래스 테이블이 상위 클래스 테이블을 참조하도록 설정하는 방식이다. 공통 속성은 상위 클래스 테이블에 저장하고, 하위 클래스마다 필요한 추가 속성은 각자의 테이블에 저장한다.

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Product { ... }

 

 

 

가장 정규화된 구조로, 다음과 같은 장/단점을 갖는다.

 

장점

  • 필요한 만큼의 데이터베이스 크기를 가진다는 장점이 있다.

단점

  • 데이터를 select할때 조인 쿼리가 필요하고 저장시에도 두번의 insert가 발생한다.

 

2. Single Table 전략

상위 클래스와 모든 하위 클래스를 하나의 통합 테이블로 변환하는 전략이다.

 

장점

  • 모든 데이터가 하나의 테이블에 저장되므로 조회 시 조인이 필요 없다.

단점

  • 불필요한 컬럼 : 모든 하위 클래스의 속성이 하나의 테이블에 들어가므로, 특정 하위 클래스에서만 사용하는 컬럼이 많아질 수 있다.
  • 저장 공간 낭비 : 위의 이유로 Null 값이 많아지며, 데이터베이스 크기가 커진다.

 

3. Table per Class 전략

Table per Class 전략은 하위 클래스마다 각각 독립적인 테이블을 생성하는 방식이다. 각 하위 클래스는 테이블은 상위 클래스의 공통 속성과 자신의 속성을 모두 포함하여 개별적으로 저장한다.

장점

  • 독립적인 테이블 구조와 하위 클래스 조회 시 조인 불필요

단점

  • 데이터 일관성 관리가 어려움 : 공통 속성이 여러 테이블에 중복 저장되면서, 데이터 변경 시 모든 테이블을 일관되게 유지해야 하는 부담이 있다. 공통 속성을 수정하거나 삭제할 때, 모든 하위 클래스 테이블을 개별적으로 수정해야 한다.
  • 상위 클래스 타입 조회 시 성능 저하 :
@SpringBootTest
@Transactional
class InheritanceTest {

    @PersistenceContext
    private EntityManager em;

    @Test
    void test() {
        Book book = new Book(10000, "Harry Potter");

        em.persist(book);
        em.flush();
        em.clear();

        Book findBook = (Book) em.find(Product.class, book.getId());
    }
}

 

Book 엔티티를 상위 타입인 Product 타입으로 조회한다고 가정해보자. 로그를 통해 수행되는 쿼리를 보면 아래와 같다.

 

    select
        p1_0.id,
        p1_0.clazz_,
        p1_0.price,
        p1_0.title,
        p1_0.name 
    from
        (select
            price,
            id,
            title,
            null as name,
            1 as clazz_ 
        from
            book 
        union
        all select
            price,
            id,
            null as title,
            name,
            2 as clazz_ 
        from
            food
    ) p1_0 
where
    p1_0.id=?

 

모든 하위 클래스 테이블에 대해 Union 쿼리가 발생한다.

 

전략 선택 기준

Joined Table

  • 각 하위 클래스가 공통 속성 외에도 다양한 고유 속성을 가지고 있을 경우. 정규화된 구조를 원하거나, 데이터 중복을 피하고자 할 때 적합하다.

Single Table

  • 하위 클래스의 종류가 많지 않고, 대다수 공통 속성만 사용할 경우. 조회 성능을 우선시할 때 적합하다.

Table per Class

  • 특정 하위 클래스만 조회할 일이 많고, 상위 클래스 타입으로 조회할 일이 거의 없는 경우에 적합하다.

'Programming > Spring,JPA' 카테고리의 다른 글

[JPA/Hibernate] Flush 차이  (0) 2024.11.22
[Spring] 예외 처리에만 국한되지 않는 @ControllerAdvice  (0) 2024.10.26
[Spring] 단일 행이 반환될때는 queryForObject가 항상 정답일까?  (0) 2024.10.26
[Spring] 스프링에서 사용되는 디자인 패턴들  (0) 2024.10.25
[Spring] 스프링 삼각형(IoC/DI, AOP, PSA)  (1) 2024.10.25
'Programming/Spring,JPA' 카테고리의 다른 글
  • [JPA/Hibernate] Flush 차이
  • [Spring] 예외 처리에만 국한되지 않는 @ControllerAdvice
  • [Spring] 단일 행이 반환될때는 queryForObject가 항상 정답일까?
  • [Spring] 스프링에서 사용되는 디자인 패턴들
우니wooni
우니wooni
  • 우니wooni
    woonDev
    우니wooni
  • 전체
    오늘
    어제
    • 전체
      • Programming
        • Java,Back-end
        • Spring,JPA
        • OS
        • Network
        • 기술 면접 대비
      • Books
        • MySQL 8.0
      • Side Project
        • Study Together
      • Life
        • 회고
        • 일상 이야기
  • 블로그 메뉴

    • 홈
    • GitHub
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    디자인 패턴
    hibernate
    JPA
    redis
    익명 클래스
    람다
    동시성 제어
    Optimistic Lock
    Persistence Context
    Pessimistic lock
    이벤트 기반 구조
    비동기
    추상화
    레디스
    Spring
    낙관적 락
    동시성
    영속성 컨텍스트
    비관적 락
    스프링
    event-driven architecture
    Java
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
우니wooni
[JPA] JPA 상속관계 매핑(@Inhertinace)
상단으로

티스토리툴바