- 상속 관계 매핑: 객체의 상속 관계를 데이터베이스에 어떻게 매핑하는지 다룬다.
- @MappedSuperclass: 등록일, 수정일 같이 여러 엔티티에서 공통으로 사용하는 매핑 정보만 상속받고 싶으면 이 기능을 사용하면 된다.
- 복합 키와 식별 관계 매핑: 데이터베이스의 식별자가 하나 이상일 때 매핑하는 방법을 다룬다. 그리고 데이터베이스 설계에서 이야기하는 식별 관계와 비식별 관계에 대해서도 다룬다.
- 조인 테이블: 테이블은 외래 키 하나로 연관관계를 맺을 수 있지만 연관관계를 관리하는 연결 테이블을 두는 방법도 있다. 여기서는 이 연결 테이블을 매핑하는 방법을 다룬다.
- 엔티티 하나에 여러 테이블 매핑하기: 보통 엔티티 하나에 테이블 하나를 매핑하지만 엔티티 하나에 여러 테이블을 매핑하는 방법도 있다. 여기서는 이 매핑 방법을 다룬다.
7.1 상속관계 매핑
객체 상속 모델
JPA에서는 상속관계를 총 3가지로 제공
- 조인 전략 : @Inheritance(strategy=InheritanceType.JOINED)
- 단일 테이블 전략 : @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
- 구현 클래스마다 테이블 전략 : @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
조인 전략
부모 테이블의 기본 키를 받아서 기본 키 + 외래 키로 사용하는 전략
객체는 타입이 있지만 테이블은 없기에 DTYPE 이라는 컬럼을 구분 컬럼으로 사용해야함
단일 테이블 전략
전략을 싱글테이블로 바꾸면된다.
추가로 자식엔티티에서 기본키 칼럼명이 다르면 @PrimaryKeyJoinColumn을 쓴다.
구현 클래스마다 테이블 전략
이전략은 이름도 길어서 제일 안쓸거 같다.. 책에서는 데이터베이스 설계자와 ORM 전문가 둘 다 추천하지 않은 전략이라고 함
7.2 @MappedSuperclass
7.1에선 테이블과의 상속관계를 다뤘는데 이건 순수히 객체의 상속만을 할땐 @MappedSuperclass를 씀 추상 클래스와 비슷하다고 생각하면 됨
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @MappedSuperclass public class BaseEntity { @Id @GeneratedValue private Long id; private String name; }
@Entity public class Member extends BaseEntity {
private String email; }
@Entity @AttributeOverride(name="id", column=@Column("MEMBER_ID")) public class Seller extends BaseEntity {
private String shopName; }
|
1 2
| @AttributeOverride @AttributeOverrides
|
어노테이션을 통해 상속받은 칼럼명을 재정의 할수도 있음.
7.3 복합 키와 식별 관계 매핑
식별 관계
비식별 관계
@IdClass와 @EmbeddedId 방식 2가지가 존재 한다.
@IdClass는 테이블 친화적이고 @EmbeddedId는 객체 친화적
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
@Entity public class Parent { @Id @Column(name="PARENT_ID") private String id;
private String name; }
@Entity @IdClass(ChildId.class) public class Child{ @Id @ManyToOne @JoinColumn(name="PARENT_ID") public Parent parent;
@Id @Column(name="CHILD_ID") private String ChildId;
private String name; }
public class ChildId implements Serializable{
private String parent;
private String childId;
}
@Entity public class GrandChild{ @Id @ManyToOne @JoinColumns({ @JoinColumn(name="PARENT_ID") ,@JoinColumn(name="CHILD_ID") }) private Child child;
@Id @Column(name="GRANDCHILD_ID") private String id;
private String name; }
public class GrandChildId implements Serializable{
private ChildId child;
private String Id;
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| @Entity public class Parent { @Id @Column(name="PARENT_ID") private String id;
private String name; }
@Entity public class Child{ @EmbeddedId private ChildId id;
@MapsId("prentId") @ManyToOne @JoinColumn(name="PARENT_ID") public Parent parent;
private String name; }
@Embeddable public class ChildId implements Serializable{
private String parentId;
@Column(name="CHILD_ID") private String id;
}
@Entity public class GrandChild{ @EmbeddedId GrandChildId id;
@MapsId("childId") @ManyToOne @JoinColumns({ @JoinColumn(name="PARENT_ID") ,@JoinColumn(name="CHILD_ID") })
private Child child;
private String name; }
@Embeddable public class GrandChildId implements Serializable{
private ChildId childId;
@Column(name="GRANDCHILD_ID") private String Id;
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| @Entity public class Parent { @Id @GeneratedValue @Column(name="PARENT_ID") private Long id;
private String name; }
@Entity public class Child{ @Id @GeneratedValue @Column(name="CHILD_ID") private Long id;
@ManyToOne @JoinColumn(name="PARENT_ID") public Parent parent;
private String name; }
@Entity public class GrandChild{ @Id @GeneratedValue @Column(name="GRANDCHILD_ID") private Long id;
@ManyToOne @JoinColumn(name="CHILD_ID") private Child child;
private String name; }
|
식별 관계인 경우는 복합키가 필요함으로 키관련 클래스들도 생성해야 하지만 비식별관계는 키가 1개임으로 복합키클래스를 만들 필요가 없다.
참고로 키가 1개일 경우만 @GeneratedValue 를 사용할수 있다.
책에서는 비식별 관계를 사용하고 기본 키는 LONG 타입의 대리 키를 사용 하는것이 좋다고 소개 되어있습니다. 그 이유는 비즈니스와 관련이 없어 변경시에 유연한 대처가 가능 Long 타입의 경우 약 920경의 숫자를 담을수 있음.
나머지 조인테이블과 엔티티 하나에 여러 테이블 매핑이 있지만 비주류라서 소개 하지 않겠습니다.
출처 : 자바 ORM 표준 JPA 프로그래밍 김영한