[JPA 기본] 상속관계 매핑

강신현·2022년 7월 16일
0

✅ @DiscriminatorColumn ✅ @DiscriminatorValue("")

상속관계 매핑

관계형 데이터베이스는 상속 관계가 없지만, 객체 상속과 유사한 슈퍼타입 서브타입 관계를 이용한다.

객체의 상속과 구조와 DB의 슈퍼타입 서브타입 관계를 매핑

슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법

1. 조인전략

  • @Inheritance(strategy = InheritanceType.JOINED)
  • 거의 이걸 씀
  • ALBUM, MOVIE, BOOK 그리고 공통된 속성을 담은 ITEM으로 각각 테이블로 변환한 뒤, DTYPE에 따라 필요한 테이블끼리 조인한다.

장점

  1. 테이블 정규화
  2. 외래 키 참조 무결성 제약조건 활용가능
  3. 저장공간 효율화

단점

  1. 조회시조인을많이사용,성능저하
  2. 조회 쿼리가 복잡함
  3. 데이터 저장시 INSERT SQL 2번 호출

코드

  • Item
    • @Inheritance(strategy = InheritanceType.JOINED)
    • @DiscriminatorColumn
@Entity
@Inheritance(strategy = InheritanceType.JOINED) // 매핑 전략 지정
@DiscriminatorColumn // DTYPE
public class Item {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private int price;
}
  • Album
@Entity
public class Album extends Item{

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

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

    private String author;
    private String isbn;
}

@DiscriminatorColumn

  • ITEM에서 사용
  • default : "DTYPE"
    name 속성으로 이름 바꿔줄 수 있음

@DiscriminatorValue("")

  • 필요시 ALBUM, MOVIE, BOOK에서 사용
  • 사용안하면 entity 값으로 들어감
  • 따로 지정하여 이름 바꿔줄 수 있음

2. 단일 테이블 전략

  • @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
  • 정말 간단할 경우에 사용
  • ITEM 테이블 하나에 필요한 모든 속성을 담아 통합 테이블(단일 테이블)로 변환한다.

장점

  1. 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
  2. 조회 쿼리가 단순함

단점

  1. 자식 엔티티가 매핑한 컬럼은 모두 null 허용
  2. 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다.
    상황에 따라서 조회 성능이 오히려 느려질 수 있다.

코드

  • Item
    - @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
    - @DiscriminatorColumn (생략 가능)
    단일 테이블에서는 해당 어노테이션을 써주지 않아도 자동으로 DTYPE이 생성된다.
    한 테이블에 모두 들어가 있으므로 앨범인지 북인지 알 수가 없기 때문
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // 매핑 전략 지정
@DiscriminatorColumn // DTYPE
public class Item {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private int price;

    public Long getId() {
        return id;
    }
}

3. 구현 클래스마다 테이블 전략

  • @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
  • 거의 안씀
  • 각 테이블 마다 공통된 속석인 NAME, PRICE을 각각 가지고 있는다.

장점

  1. 서브 타입을 명확하게 구분해서 처리할 때 효과적
  2. not null 제약조건 사용 가능

단점

  1. 여러 자식 테이블을 함께 조회할 때 성능이 느림(UNION SQL 필요)
  2. 자식 테이블을 통합해서 쿼리하기 어려움

코드

  • Item
    • @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    • 추상 클래스(abstract)로 변경 : 그래야 Item이 따로 안만들어짐
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) // 매핑 전략 지정
@DiscriminatorColumn // DTYPE
public abstract class Item {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private int price;

    public Long getId() {
        return id;
    }
}

trouble shooting

1. ddl-auto : create 일때 테이블 drop시 에러

h2 데이터베이스 1.4.200에서 발생하는 문제이다.

  • 해결방안1
    h2 데이터베이스 버전을 1.4.199로 낮춘다.
  • 해결방안2
    h2 데이터베이스 버전을 1.4.200을 유지하고, 하이버네이트 버전을 5.4.13.Final 버전 이상부터 사용한다.

하이버네이트 5.4.13.Final 부터 H2 데이터베이스 1.4.200을 제대로 지원한다.
drop 테이블 이슈도 해결됨

https://www.inflearn.com/questions/52796

2. Error:java: error: release version 5 not supported

pom.xml의 dependencies 태그 안에

<dependency>
    <groupId>javax.xml.bind</groupId>
     <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
 </dependency>

넣고 xml 새로고침 한뒤에

File -> Settings -> Build, Execution, Deployment -> Java Compiler 순으로 타고 들어가서

Java Compiler 내용들 중 Project bytecode version과 Per-module bytecode version 속 저희 프로젝트 이름 모듈의 Target bytecode version의 값을 둘다 8로 바꿔줌

https://www.inflearn.com/questions/19302

profile
땅콩의 모험 (server)

0개의 댓글