흰 스타렉스에서 내가 내리지

[JPA] 복합 키 : 식별 관계 매핑 본문

Spring

[JPA] 복합 키 : 식별 관계 매핑

주씨. 2023. 2. 11. 23:45
728x90

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

식별 관계에서 자식 테이블은 부모 테이블의 기본 키를 포함해서 복합 키를 구성해야 하므로 @IdClass 나 @EmbeddedId를 사용해서 식별자를 매핑해야 한다.

 

@IdClass와 식별관계

@Entity
@Getter @Setter
public class Parent {
    @Id 
    @Column(name = "PARENT_ID")
    private Long id;
    
    private String name;
}

@Entity
@Getter @Setter
@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;  // Child.parent 매핑
    private String childId; // Child.childId 매핑

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }
}

@Entity
@IdClass(GrandChildId.class)
@Getter @Setter
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;  // GrandChild.child
    private String id;  // GrandChild.id

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }
}

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

 

 

@EmbeddedId와 식별관계

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

@Entity
@Getter @Setter
public class Parent {
    @Id
    @Column(name = "PARENT_ID")
    private Long id;

    private String name;
}

@Entity
@Getter @Setter
public class Child {
    @EmbeddedId
    private ChildId id;
    
    @MapsId("parentId") //ChildId.parentId 매핑
    @ManyToOne
    @JoinColumn(name = "PARENT_ID")
    public Parent parent;

    private String name;
}


@Embeddable
public class ChildId implements Serializable {
    private String parentId;    //@MapsId("parentId")로 매핑

    @Column(name = "CHILD_ID")
    private String id;

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }
}

@Entity
@Getter @Setter
public class GrandChild {
    @EmbeddedId
    private GrandChildId id;
    
    @MapsId("childId")  // GrandChildId.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;  // @MapsId("childId")로 매핑
    
    @Column(name = "GRANDCHILD_ID")
    private String id;
    
    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }
}

@EmbeddedId는 식별 관계로 사용할 연관관계의 속성에 @MapsId를 사용하면 된다.

@IdClass와 다른 점은 @Id 대신에 @MapsId를 사용한 점이다.

@MapsId는 외래 키와 매핑한 연관관계를 기본 키에도 매핑하겠다는 뜻이다.

@MapsId의 속성 값은 @EmbeddedId를 사용한 식별자 클래스의 기본 키 필드를 지정하면 된다.