상속 관계 매핑을 공부해본다. (김영한의 JPA 고급매핑)
상속관계 매핑은 객체의 상속관계를 데이터베이스에 어떻게 매핑할지 정하는 것이다.
엔티티 각각을 테이블로 만들고 자식이 부모 테이블의 기본키를 받아 pk + fk로 쓰는 전략이다.
테이블은 타입 개념이 없어서 타입을 구문하는 컬럼을 추가해줘야한다.
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item {
@Id
@GeneratedValue
@Column(name = "ITEM_ID")
private Long id;
private String name;
private int price;
}
@Entity
@DiscriminatorValue("A")
public class Album extends Item{
private String artist;
}
조인전략을 쓰면 테이블이 정규화되고 외래키 참조 무결성 제약조건을 활용할 수 있지만 성능저하가 있을 수 있고,
조회 쿼리가 복잡해진다. 실제로 테이블을 여러개를 left join으로 활용하고 있는데 쿼리를 볼 때마다 어디까지 조회되는지 헷갈린다 ㅠㅠ
테이블 하나에 모든 값을 넣는 전략이다. 단점은 관련이 없는 컬럼의 경우 null을 허용해줘야 오류가 안생긴다.
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 단일 테이블임을 알려주고 구분값을 넣어주면된다.
각각의 테이블에 Item의 id 값을 넣어주는 전략이다.
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
not null 제약조건을 쓸 수 있지만 여러 테이블을 함께 조회할 때 성능이 느리다.
만약 부모 클래스와 자식 클래스를 직접 매핑하지 않고 자식 클래스에 부모 클래스의 매핑 정보만 제공하고 싶다면 @MappedSuperclass를 활용하면 된다.
@MappedSuperclass
public abstract class BasicEntity {
@Id
@GeneratedValue
private Long id;
private String name;
}
BasicEntity를 만들고 자식에 공통적으로 들어가는 속성을 넣어준다.
그리고 자식 엔티티에서는 public class Member extends BasicEntity 해주면 공통 속성이 함께 들어가게 된다.
만약에 물려받은 매핑 정보를 재정의하려면
@AttributeOverrides({
@AttributeOverride(name = "id", column = @Column(name = "MEMBER_ID")),
@AttributeOverride(name = "name", column = @Column(name = "MEMBER_NAME"))
})
public class Member extends BasicEntity{
여기서 중요한 것은 @MappedSuperclass는 단순히 공통으로 사용하는 정보를 엔티티에 모아주는 역할만 한다.