-
[JPA] 상속관계 맵핑 @Inheritance, @DiscriminatorColumnJPA 2023. 6. 25. 15:03
상속관계 맵핑 @Inheritance, @DiscriminatorColumn
안녕하세요? 장장스입니다.
JPA 상속관계 맵핑 @MappedSuperclass 에 대해 정리해보겠습니다.
상속관계 맵핑
일반적인 관계형 데이터베이스는 슈퍼타입 서브타입 관계라는 모델링 기법이 있습니다.
JPA에서는 슈퍼타입 서브타입 관계를 상속을 활용하여 구현할 수 있습니다.
@Inheritance
@Inheritance 어노테이션의 strategy 속성을 통해 전략을 선택 할 수 있습니다.
@DiscriminatorColumn 어노테이션은 부모 클래스에 선언합니다. 하위클래스를 구분하는 용도의 칼럼을 사용합니다. name 속성을 통해 이름을 설정할 수 있습니다. default 값은 DTYPE 입니다.
@Entity @Getter @Setter @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn public abstract class Item { @Id @GeneratedValue private Long id; private String name; private int price; }
하위 클래스는 상위 클래스를 상속 받습니다. 이때 @DiscriminatorValue 어노테이션으로 엔티티를 저장할 때 슈퍼타입의 구분 칼럼에 저장할 값을 지정합니다. 선언하지 않으면 클래스 이름이 기본값으로 들어가게 됩니다.
@Entity @Getter @Setter @DiscriminatorValue(value = "A") public class Album extends Item{ private String artist; } @Entity @Getter @Setter @DiscriminatorValue(value = "B") public class Book extends Item{ private String author; private String isbn; } @Entity @Getter @Setter @DiscriminatorValue(value = "M") public class Movie extends Item{ private String director; private String actor; }
InheritanceType.JOINED 전략
일반적인 정규화 된 방법으로 구현하는 전략입니다. @DiscriminatorColumn을 선언해야만 DTYPE 칼럼이 생성됩니다. 조인을 통해 어떤 하위 클래스인지 확인을 할 수 있으나 명확한 구분을 위해 DTYPE을 선언하는게 좋습니다.
다만, 조회시 조인을 많이사용하게 되고 쿼리가 복잡해질 수 있어 성능저하가 올 수 있습니다. 추가로 테이블에 데이터 저장시 INSERT SQL 2번 호출하게 됩니다.
InheritanceType.SINGLE_TABLE 전략
하나의 테이블에 모두 저장하고 DTYPE으로 구분하는 전략입니다. 하나의 테이블에 모두 저장하기 때문에 DTYPE 없이는 구분을 할 수 없어 @DiscriminatorColumn 을 선언하지 않아도 DTYPE칼럼이 생성됩니다.
INSERT SQL 1번만 호출하게 됩니다. 자식 엔티티가 매핑한 컬럼은 모두 null 사용을 하게 됩니다, 하나의 테이블에 모든 데이터를 저장하므로 테이블이 커질 수 있습니다. 때문에 상황에 따라서 조회 성능이 오히려 느려질 수 있습니다.
InheritanceType.TABLE_PER_CLASS 전략 (비추천)
JOINED 전략과 유사하지만 슈퍼타입(여기서는 Item) 칼럼들을 서브타입으로 내리는 전략입니다. 각각의 구현 클래스마다 테이블 생성 전략을 적용 할 수 있으며, NOT NULL 제약조건을 사용할 수 있습니다.
그러나, 여러 자식 테이블을 함께 조회하기 위해서는 UNION SQL 을 사용해야만 합니다. 때문에 SQL 조회 성능이 떨어지게 고 여러 자식 테이블을 통합해서 SQL을 사용하기가 어렵습니다.
Post
References
잘못된 코드나 내용이 있다면 댓글을 남겨주세요. 즉시 수정하도록 하겠습니다! :)
'JPA' 카테고리의 다른 글