인프런 커뮤니티 질문&답변

butterfly black님의 프로필 이미지
butterfly black

작성한 질문수

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

엔티티 클래스 개발2

셀프로 양방향 연관관계 관련 질문입니다.

작성

·

559

3

안녕하세요, 

먼저 강의를 잘 듣고 있는 학생 1인 입니다. ㅎㅎ

엔티티 클래스 개발2 강의 중

셀프로 양방향 연관관계 관련 질문입니다. 

Category 엔티티에서 

// 자식입장에서 바라보는 부모

@ManyToOne(fetch = FetchType.LAZY)

@JoinColumn(name = "parent_id")

   private Category parent;

위의 JoinColumn시 "category_id"가 아니라, "parent_id"로 작성해야 되는 이유를 알 수 있을까요?

셀프를 제외한 일반적인 양방향 연관관계에서 "연관관계 주인" 쪽에서 연관관계 거울 쪽을 Join할 때

연관관계 거울의 KEY를 명시해 주는데, 이와 마찬가지로 parent_id가 아닌 category_id가 아닌지... 궁금합니다.

실제로 바꿔서 했을 때, 오류가 발생했습니다...

답변 4

3

아! 저도 이해했습니다.

말씀해주신 것처럼

@JoinColumn의 referencedColumnName 의 default 속성을 보니 이해했습니다. 

앞으로 어노테이션 관련 속성을 꼭 들어다 보겠습니다.

친절한 설명 감사합니다.^^ 수고하십시요

2

김영한님의 프로필 이미지
김영한
지식공유자

butterfly black님^^ 질문을 이해했습니다.

@JoinColumn에는 referencedColumnName 이라는 속성이 있는데요. 이게 바로 비밀의 키 입니다. 여기에 아무 값도 지정하지 않으면 대상 테이블의 PK를 지정합니다. 따라서 parent_id는 FK가 되고, 이 FK가 가리키는 곳이 Category parent의 PK인 category_id가 되는 것이지요^^

도움이 되셨길 바래요.

1

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. butterfly black님^^

좀 쉽게 풀어서 셀프로 이해하면 조금 어려우니 ParentCategory, ChildCategory라고 할께요.

하나의 부모가 여러 자식 카테고리를 가지는 구조이니까

ParentCategory가 1이고,  ChildCategory가 N이 됩니다.

그러면 연관관계의 주인은 어디가 되어야 할까요?

바로 N쪽인 ChildCategory가 연관관계의 주인이 되어야 하지요^^

왜냐하면 연관관계의 주인은 비즈니스상 중요한 것이 기준이 되는게 아니라 DB FK가 있는(일다대 에서는 N쪽이) 곳이 연관관계의 주인이 되어야 합니다.

그래서 코드를 풀어보자면 다음과 같이 됩니다.

ParentCategory{

    @OneToMany(mappedBy = "parent")

    private List<Category> child = new ArrayList<>(); //연관관계의 거울

}

ChildCategory {

    @ManyToOne

    @JoinColumn(name = "parent_id")

    private Category parent; //연관관계의 주인

}

도움이 되셨길 바래요^^

0

친절한 답변 감사합니다..... 그런데, 제가 궁금한 부분은 아직 해결이 안된 듯 하여, 보충설명 적어놓았습니다.....

1. 작성 해주신 코드에다가 ID만 덧붙이면 아래와 같습니다.

ParentCategory{

    @Id

    @GeneratedValue

    @Column(name = "parent_id")

    private long id;

    @OneToMany(mappedBy = "parent")

    private List<Category> child = new ArrayList<>(); //연관관계의 거울

}

ChildCategory {

    @Id

    @GeneratedValue

    @Column(name = "child_id")

    private long id;

    @ManyToOne

    @JoinColumn(name = "parent_id")

    private Category parent; //연관관계의 주인

}

2. 이렇게 Entity가 분리된 상태에서는 

"ChildCategory의 @JoinColumn(name = "parent_id")에서 "parent_id" 이 코드는

ParentCategory의 @Column(name = "parent_id")를 맵핑하여 찾는다" 라고 쉽게 이해할 수 있습니다.

3. 그런데 Self로 연결하는 경우

public class Category {

    @Id

    @GeneratedValue

    @Column(name = "category_id")

    private Long id;

  

    @ManyToOne(fetch = FetchType.LAZY)

    @JoinColumn(name = "parent_id") // 1) 여기서 "parent_id"는 위와는 다르게  "parent_id" 가 명시적으로

                                                     작성해 놓은 곳이 없는데...

                                          //  2) 즉, 위와 다르게 JOIN 연결고리가 안보여서(혹은 제가 이해를 못한거 같긴합니다...)

                                         //   3) "category_id"로 연결해야 되는게 아닌지....

                                         //  4) 아니면 네이밍룰이 별도로 있어서 그런건지... 그게 궁금했습니다....

    private Category parent;

 

    @OneToMany(mappedBy = "parent")

    private List<Category> child = new ArrayList<Category>();

감사합니다....

butterfly black님의 프로필 이미지
butterfly black

작성한 질문수

질문하기