[번들러 프로젝트] 상속관계 @DiscriminatorValue를 컬럼으로 뽑아내기

이혜지·2023년 2월 24일
0

Bundler PJT

목록 보기
4/5
post-custom-banner

1. 문제


상속 관계 매핑


객체에는 상속관계가 존재하지만, 관계형 데이터베이스에는 상속 관계가 대부분 없다.

슈퍼타입 서브타입 관계라는 모델링 기법이 객체의 상속과 유사하다.

상속관계 매핑이라는 것은 객체의 상속 구조와 DB의 슈퍼타입 서브타입 관계를 매핑하는 것

슈퍼타입 서브타입 논리 모델 → 물리모델

  • 객체는 상속을 지원하므로 모델링과 구현이 똑같지만, DB는 상속을 지원하지 않으므로 물리 모델로 구현할 방법이 필요하다.
  • DB의 슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법은 세가지가 있다. (조인 전략, 싱글 전략, 구현 클래스 테이블 전략)
  • JPA에서 세가지 방식
    • @Inheritance(strategy=InheritanceType.XXX)의 strategy를 설정해주면 된다.
      • default전략은 SINGLE_TABLE(단일 테이블 전략)이다.
      • InheritanceType 종류
        • JOINED
        • SINGLE_TABLE
        • TABLE_PER_CLASS
    • @DiscriminatorColumn(name=”DTYPE”)
      • 부모 클래스에 선언한다. 하위 클래스를 구분하는 용도의 컬럼이다. 관례는 default = DTYPE
    • @DiscriminatorValue(”XXX”)
      • 하위 클래스에 선언한다. 엔티티를 저장할 때 슈퍼타입의 구분 컬럼에 저장할 값을 지정한다.
      • 어노테이션을 선언하지 않을 경우 기본값으로 클래스 이름이 들어간다.
  • 객체의 상속 관계 구현 예시
    • Item.class

      @Entity
      @Inheritance(strategy = InheritanceType.XXX) // 상속 구현 전략 선택
      public class Item {
      
         @Id
         @GeneratedValue(strategy = GenerationType.IDENTITY)
         private Long id;
      
         private String name;
         private int price;
      }
    • Album.class

      @Entity
      public class Album extends Item {
      
         private String artist;
      }
    • Movie.class

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

      @Entity
      public class Book extends Item {
      
         private String author;
         private String isbn;
      }

조인 전략 (각각의 테이블로 변환)

  • 가장 정규화 된 방법으로 구현하는 방식이다.
  • NAME, PRICE가 ITEM 테이블에만 저장되고, ALBUM, MOVIE, BOOK이 각자의 데이터만 저장한다.
  • Item 엔티티 - @Inheritance(strategy = InheritanceType.JOINED) 전략
    • 하이버네이트의 조인 전략에서는 @DiscriminatorColumn을 선언하지 않으면 DTYPE 컬럼이 생성되지 않는다.
    • 어차피 조인하면 앨범인지 무비인지 알 수 있다. 그래도, DTYPE을 넣어주는 것이 명확하다. 넣어주자.
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn // 하위 테이블의 구분 컬럼 생성(default = DTYPE)
public class Item {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;

   private String name;
   private int price;
}

[Spring JPA] 상속 ( JOINED 전략을 중심으로 )

2. 고민


@DiscriminatorValue 으로 뽑아낸 걸
자식에서 조회했을 때 FeedType이라는 enum을 넘겨주고싶었다.
하지만 부모에서 가지고있는데 어케하지?

3. 결론


@Transient를 이용해서 그냥 디비에 값이 중복되지않게 하고
Enum타입을 자식에 주고 그걸로 조회했다.

	@Transient
	@Column(name = "feed_type")
	@Enumerated(EnumType.STRING)
	private FeedType feedType;

이렇게!

profile
공유 문화를 지향하는 개발자입니다.
post-custom-banner

0개의 댓글