본문 바로가기

JPA

7.3.3 복합키 : 식별관계 매핑

부모, 자식, 손자까지 계속 기본 키를 전달하는 식별 관계다.

 

@IdClass와 식별 관계

//부모
@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;
}

//자식 Id
public class ChildId implements Serializable {

    private String parent; //Child.parent 매핑
    private String childId; //Child.childId 매핑
    
    //equals, hashCode
}

//손자
@Entity
@IdClass(GrandChildId.class)
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;
}

//손자 ID
public class GrandChildId implements Serializable {

    private ChildId child; //GrandChild.child 매핑
    private String id;
    
    //equals, hashCode
}

 

식별관계는 기본키와 외래키를 같이 매핑해야 한다. 따라서 식별자 매핑인 @Id와 연관관계 매핑인 @ManyToOne을 같이 사용하면 된다.

 

@EmbeddedId와 식별관계

@EmbeddedId로 식별관계를 구성할 때는 @MapsId를 사용해야 한다.

//부모
@Entity
public class Parent {

    @Id @Column(name = "PARENT_ID")
    private String id;
    private String name;
}

@Entity
public class Child {

    @MapsId("parentId") //Child.parentId 매핑
    @ManyToOne
    @JoinColumn(name = "PARENT_ID")
    public Parent parent;
    
    @EmbeddedId
    private ChildId childId;
    
    private String name;
}

//자식 Id
@Embeddable
public class ChildId implements Serializable {

    private String parentId; //@MapsId("parentId")로 매핑
    
    @Column(name = "CHILD_ID")
    private String id;
    
    //equals, hashCode
}

//손자
@Entity
public class GrandChild {

    @EmbeddedId
    private GrandChildId id;
    
    @MapsId("childId")
    @ManyToOne
    @JoinColumns({
    	@JoinColumn(name = "PARENT_ID"),
        @JoinColumn(name = "CHILD_ID")
    })
    private Child child;
    
    private String name;
}

//손자 ID
@Embeddable
public class GrandChildId implements Serializable {

    private ChildId child; //@MapsId("childId")로 매핑
    
    @Column(name = "GRANDCHILD_ID")
    private String id;
    
    //equals, hashCode
}

 

@MapsId는 외래키와 매핑한 연관관계를 기본키에도 매핑하겠다는 뜻이다. @MapsId의 속성 값은 @EmbeddedId를 사용한 식별자 클래스의 기본키 필드를 지정하면 된다. 여기서는 ChildId의 parentId필드를 선택했다.

 

7.3.4 비식별관계로 구현

 

//부모
@Entity
public class Parent {

    @Id @GenerateValue
    @Column(name = "PARENT_ID")
    private Long id;
    private String name;
}

//자식
public class Child {

    @Id @GeneratedValue
    @Column(name = "CHILD_ID")
    private Long id;
    private String name;
    
    @ManyToOne
    @JoinColumn(name = "PARENT_ID")
    private Parent parent;
}

//손자
@Entity
public class GrandChild {

    @Id @GeneratedValue
    @Column(name = "GRANDCHILD_ID")
    private Long id;
    private String name;
    
    @ManyToOne
    @JoinColumn(name = "PARENT_ID")
    private Parent parent;
}

//손자
@Entity
public class GrandChild {

    @Id @GeneratedValue
    @Column(name = "GRANDCHILD_ID")
    private Long id;
    private String name;
    
    @ManyToOne
    @JoinColumn(name = "CHILD_ID")
    private Child child;
}

비식별 관계의 코드는 복합키를 사용하지 않으므로 매핑도 쉽고 코드도 단순하다.

'JPA' 카테고리의 다른 글

13.2.1 글로벌 페치 전략 수정  (0) 2021.01.29
13.1 트랜잭션 범위의 영속성 컨텍스트  (0) 2021.01.28
7.2 @MappedSuperClass  (0) 2021.01.17
7.1 상속관계 매핑  (0) 2021.01.17
8.6 영속성 전이 + 고아객체, 생명주기  (0) 2021.01.17