[DB] 테이블을 설계하자! -4

복합 키와 식별 관계 매핑

식별 관계 vs 비식별 관계

식별 관계


식별 관계는 부모 테이블의 기본키를 내려 받아서 자식 테이블의 기본키와 외래키로 사용

비식별 관계

비식별 관계는 부모 테이블의 기본 키를 받아서 자식 테이블의 외래 키로만 사용하는 관계이다.

*필수적 비식별 관계
-외래 키에 NULL을 허용하지 않는다. 연관 관계를 필수로 맺어야 한다.

*선택적 비식별 관계
-외래 키에 NULL을 허용한다. 연관 관계를 맺을지 말지 선택할 수 있다.

" JPA에서 식별자를 둘 이상 사용하려면 별도의 식별자 클래스가 필요하다."

복합 키 : 비식별 관계 매핑

@Entity
public class Hello {

    @Id
    private String id;

    @Id
    private string id2;

" JPA에서 식별자를 둘 이상 사용하려면 별도의 식별자 클래스가 필요하다."

@IdClass

@Entity
@IdClass(ParentId.class)
public class Parent {

    @Id
    @Column(name = "PARENT_ID1")
    private String id1; // ParentId.id1과 연결

    @Id
    @Column(name = "PARENT_ID2")
    private String id2; // ParentId.id2와 연결

    private String name;

}

public class ParentId implements Serializable {

    private String id1;
    private String id2;

    // 생성자
    // equals, hashCode

}
 

@IdClass를 사용할 때 식별자 클래스는 다음 조건을 만족해야 한다.

식별자 클래스의 속성명과 엔티티에서 사용하는 식별자의 속성명이 같아야 한다.
예제의 Parent.id1, Parent.id2와 ParentId.id1, ParentId.id2는 같다.
Serializable 인터페이스를 구현해야 한다.
equals, hashCode를 구현해야 한다.
기본 생성자가 있어야 한다.
식별자 클래스는 public이어야 한다.

이제, 자식 클래스에서 외래 키로 연결해 보자.

Entity
public class Child {

    @Id
    private String id;

    @ManyToOne
    @JoinColumns({
            @JoinColumn(name = "PARENT_ID1",
                referencedColumnName = "PARENT_ID1"),
            @JoinColumn(name = "PARENT_ID2",
                referencedColumnName = "PARENT_ID2")
    })
    private Parent parent;

}

참고> 예제처럼 @JoinColumn의 name 속성과 referencedColumnName 속성의 값이 같으면 후자는 생략해도 된다.

@EmbeddedId

@Entity
public class Parent {

    @EmbeddedId
    private ParentId id;

    private String name;

}

@Embeddable
public class ParentId implements Serializable {

    @Column(name = "PARENT_ID1")
    private String id1;

    @Column(name = "PARENT_ID2")
    private String id2;

    // 생성자 구현
    // equals, hashCode 구현

}

Parent 엔티티에 식별자 클래스를 직접 사용하고, @EmbeddedId 어노테이션을 적어주면 된다. @IdClass와 다르게 @EmbeddedId를 적용한 식별자 클래스는 식별자 클래스에 기본 키를 직접 매핑한다.

@EmbeddedId를 적용한 식별자 클래스는 다음 조건을 만족해야 한다.

1.@Embeddable 어노테이션을 붙여주어야 한다.
2.Serializable 인터페이스를 구현해야 한다.
3.equals, hashCode를 구현해야 한다.
4.기본 생성자가 있어야 한다.
5.식별자 클래스는 public 이어야 한다.

@IdClass vs @EmbeddedId

후자가 좀 더 객체지향적이어서 많이 쓰지만, 장단점이 있으므로 본인의 취향에 맞게 사용하면 된다.

주의 사항

복합 키에는 @GenerateValue를 사용할 수 없다.

좋은 웹페이지 즐겨찾기