김영한의 ORM 표준 JPA 프로그래밍(기본편) - 상속관계 맵핑과 - @MappedSuperclass

2025. 2. 6. 21:37·김영한의 ORM 표준 JPA 프로그래밍(기본편)

Question

  • JPA에서 상속관계 맵핑하는 방법들에 대해 설명하시오
  • JPA에서 상속관계 맵핑하는 방법에 관해 실무에서 어떻게 적용하면 좋은지 설명하시오
  • JPA 상속 관계에서 부모 클래스에 @DiscriminatorColumn을 명시하지 않으면 디폴트 구분자로 사용되는 컬럼명은?
  • JPA 상속 관계에서 하위 클래스에 @DiscriminatorValue로 명시하지 않으면 디폴트 값으로 사용되는 것은?
  • @MappedSuperclass는 언제 사용하면 좋은가?

 

상속관계 맵핑 방법

  • 객체는 상속이 있지만 관계형 데이터베이스는 상속 관계가 없음
  • 슈퍼타입 - 서브타입 관계라는 모델링 기법이 객체 상속과 유사
  • 실제 구현 방법 3가지
    • 조인 전략: 부모, 자식을 각 테이블로 변환 후 조인
    • 단일 테이블 전략: 자식들을 부모에 합쳐 한 테이블로 변환
    • 클래스마다 각 테이블 전략: 부모를 각 자식들에 합쳐 여러 테이블로 변환

 

주요 어노테이션

  • @Inheritance(strategy = InheritanceType.XXX)
    • JOINED: 조인 전략
    • SINGLE_TABLE: 단일 테이블 전략
    • TABLE_PER_CLASS: 클래스마다 각 테이블 전략
  • @DistriminatorColumn(name = "DTYPE")
  • @DiscriminatorValue("XXX)

 

 

조인 전략

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item{
	@Id @GeneratedValue
	private Long id;
	...
}

@Entity
@DiscriminatorValue("Album")
public class Album extends Item {
	private String artist
}
  • 효율적으로 잘 사용해야할 때 사용하는 방식
  • @DiscriminatorColumn을 명시하지 않으면 자동으로 DTYPE이라는 컬럼이 구분자로 사용되며, 해당 값으로 해당 ITEM_ID가 어느 하위 테이블과 연관이 있는지 파악을 할 수 있음.
  • @DiscriminatorColumn을 명시하면 DTYPE 대신 해당 컬럼 네임으로 구분자를 사용 가능
  • DTYPE 구분자의 Value로 들어갈 하위 테이블의 이름은 @DiscriminatorValue로 명시할 수 있으며 명시하지 않으면 기본적으로 해당 테이블의 이름이 들어감
  • insert시 Item, Album 모두에 값이 들어가게 되며 find시 join을 통해 가져옴
  •  장점
    • 테이블 정규화
    • 외래 키 참조 무결성 제약조건 활용 가능
    • 저장공간 효율화
  • 단점
    • 조회시 조인을 많이 사용해 성능이 저하될 수 있음
    • 조회 쿼리의 복잡성
    • 데이터 저장시 INSERT SQL 2번 호출

 

단일 테이블 전략

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
public abstract class Item{
	@Id @GeneratedValue
	private Long id;
	...
}
  • 조인 전략에 비해 간단할 경우에 사용하며, 기본적으로 단일 테이블 전략을 사용하다가 정교한 컨트롤이 필요할 때 조인 전략으로 넘어가도 됨
  • 단일 테이블 전략에서는 @DiscriminatorColumn 구분자가 필수인데, 코드상으로는 명시하지 않아도 자동 DTYPE으로 생성 됨.
  •  장점
    • 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
    • 조회 쿼리가 단순
  • 단점
    • 자식 엔티티가 맵핑한 컬럼은 모두 null을 허용해야 함
    • 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있고, 따라서 상황에 따라 조회 성능이 오히려 느려질 수 있음

 

클래스마다 각 테이블 전략

  • DB 설계자, ORM 전문가 모두 추천하지 않는 방식으로 사용하면 안됨
  • 장점
    • 서브 타입을 명확하게 구분해서 처리할 때 효과적
    • not null 제약조건을 사용할 수 있음
  • 단점
    • 여러 자식 테이블을 함께 조회할 때 성능이 느림(UNION SQL 필요)
      자식 테이블을 통합해서 쿼리하기 어려움

 

 

@MappedSuperclass

@MappedSuperclass
public abstract class BaseEntity {
	private String createBy;
	private LocalDateTime createdDate;
	private String lastModifiedBy;
	private LocalDateTime lastModifiedDate;
    
	...
}

@Entity
public class Team extend BaseEntity{
...
  • 실제 상속의 개념은 아니고 속성만 상속하는 개념
  • 예를 들어, 모든 테이블에 create_dt, create_user, update_dt, update_user가 있어야 하는 경우 BaseEntity에 해당 값 추가해주고 이 속성이 필요한 다른 테이블에서 해당 테이블을 extend
  • BaseEntity는 직접 사용할 일이 없으므로 abstract으로 선언하는게 좋음
  • 참고로 @Entity 클래스는 @Entity나 @MappedSuperclass로 지정한 클래스만 상속 가능함

'김영한의 ORM 표준 JPA 프로그래밍(기본편)' 카테고리의 다른 글

김영한의 ORM 표준 JPA 프로그래밍(기본편) - 값타입, 임베디드 타입, 값 타입 컬렉션  (3) 2025.02.08
김영한의 ORM 표준 JPA 프로그래밍(기본편) - 프록시, 지연로딩, Cascade, 고아 객체  (1) 2025.02.07
김영한의 ORM 표준 JPA 프로그래밍(기본편) - 다대일, 일대다, 일대일, 다대다  (1) 2025.02.05
김영한의 ORM 표준 JPA 프로그래밍(기본편) - 연관관계 단방향 맵핑, 양방향 맵핑  (1) 2025.02.05
김영한의 ORM 표준 JPA 프로그래밍(기본편) - 연관관계맵핑과 Primary Key  (2) 2025.02.05
'김영한의 ORM 표준 JPA 프로그래밍(기본편)' 카테고리의 다른 글
  • 김영한의 ORM 표준 JPA 프로그래밍(기본편) - 값타입, 임베디드 타입, 값 타입 컬렉션
  • 김영한의 ORM 표준 JPA 프로그래밍(기본편) - 프록시, 지연로딩, Cascade, 고아 객체
  • 김영한의 ORM 표준 JPA 프로그래밍(기본편) - 다대일, 일대다, 일대일, 다대다
  • 김영한의 ORM 표준 JPA 프로그래밍(기본편) - 연관관계 단방향 맵핑, 양방향 맵핑
5jyan5
5jyan5
  • 5jyan5
    jyan
    5jyan5
  • 전체
    오늘
    어제
    • 분류 전체보기 (242)
      • 김영한의 스프링 핵심 원리(기본편) (8)
      • 김영한의 스프링 핵심 원리 - 고급편 (11)
      • 김영한의 스프링 MVC 1편 (1)
      • 김영한의 스프링 DB 1편 (3)
      • 김영한의 스프링 MVC 2편 (3)
      • 김영한의 ORM 표준 JPA 프로그래밍(기본편) (9)
      • 김영한의 스프링 부트와 JPA 활용2 (2)
      • 김영한의 실전 자바 - 중급 1편 (1)
      • 김영한의 실전 자바 - 고급 1편 (9)
      • 김영한의 실전 자바 - 고급 2편 (9)
      • Readable Code: 읽기 좋은 코드를 작성.. (2)
      • 김영한의 실전 자바 - 고급 3편 (9)
      • CKA (118)
      • 개발 (37)
      • 경제 (4)
      • 리뷰 (1)
      • 정보 (2)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      프록시
      프록시 팩토리
      페치 조인
      Thread
      jpq
      jdk 동적 프록시
      @discriminatorcolumn
      버퍼
      WAS
      김영한
      고급
      JPQL
      락
      양방향 맵핑
      스레드
      @args
      빈 후처리기
      typequery
      hibernate5module
      gesingleresult
      @within
      조회 성능 최적화
      @discriminatorvalue
      log trace
      requset scope
      cglib
      reentarantlock
      Target
      단방향 맵핑
      자바
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.2
    5jyan5
    김영한의 ORM 표준 JPA 프로그래밍(기본편) - 상속관계 맵핑과 - @MappedSuperclass
    상단으로

    티스토리툴바