본문 바로가기
Book

자바 ORM 표준 JPA 프로그래밍 - JPA 정리하기 (5-2) 연관관계 매핑 기초

by devLog by Ronnie's 2022. 8. 7.

들어가며


5강은 1편과 2편으로 나눠 진행하였다. 5강에서는 연관관계에 대해서 나올 수 있는 모든 케이스를 설명을 하여 다소 헷갈리는 부분들이 있었다. 여러번 읽어보고 케이스들을 숙지해야 될 것 같다.

 

 

5.3 양방향 연관관계

  • 회원과 팀은 다대일 / 반대로 팀에서 회원은 일대다 관계
  • 일대다 관계는 여러 건과 연관관계를 맺을 수 있으므로 컬렉션을 사용

5.3.1 양방향 연관관계 매핑

  • 일대다 관계이므로 팀 엔티티에 컬렉션인 List<Member> 컬렉션 추가를 한다.
  • 팀에서는 @OneToMany 로 매핑한다. (일대다 매핑정보)
  • mappedBy 속성은 양방향 매핑일 때 사용하며 반때쪽 매핑의 필드 이름을 값으로 준다.
  • 반대쪽 매핑이 Member.team 을 사용하므로 team 을 값으로 준다.

5.4 연관관계의 주인

  • 객체에는 양방향 연관관계라는 것이 없다.
  • 서로 다른 단방향 연관관계 2개를 애플리케이션 로직으로 잘 묶어서 양방향인 것처럼 보이게 할 뿐
  • 반면 디비 테이블은 외래 키 하나로 양쪽이 서로 조인 가능
  • 따라서 테이블은 외래 키 하나로 양방향 연관관계를 맺는다.
  • 엔티티를 단방향으로 매핑하면 참조를 하나만 사용하므로 이 참조로 외래 키를 관리하면 된다.
  • 하지만 엔티티를 양방향으로 미팽하면 두 곳에서 서로를 참조한다.
  • 그러므로 객체의 연관관계를 관리하는 포인트는 2곳으로 늘어나게 되며 테이블에서 외래키로 관리하는 것과 차이가 발생하게 된다.
  • 이 때 두 객체 연관관계 중 하나를 정해서 테이블의 외래키를 관리해야 하는데 이것은 연관관계의 주인이라고 한다.

5.4.1 양방향 매핑의 규칙: 연관관계의 주인

  • 양방향 연관관계 매핑 시 두 연관관계 중 하나를 연관관계의 주인으로 정해야 한다.
  • 연관관계의 주인만이 디비 연관관계와 매핑되고 외래 키를 관리(등록, 수정, 삭제)할 수 있다.
  • 반면 주인이 아닌 쪽은 읽기만 가능
  • 연관관계 주인을 정할지는 mappedBy 속성을 통해 가능
  • 주인은 mappedBy 속성을 사용하지 않는다.
  • 주인이 아닌쪽에 mappedBy 속성을 사용해서 속성의 값으로 연관관계의 주인을 지정

5.4.2 연관관계의 주인은 외래 키가 있는 곳

  • 연관관계의 주인은 테이블에 외래 키가 있는 곳으로 정함
  • 회원 테이블이 외래 키(TEAM_ID)를 가지고 있으므로 Member.team이 주인이 된다.
  • 주인이 아닌 Team.members에는 mappedBy=“team”으로 설정
  • 디비 테이블의 다대일, 일대다 관계에서는 항상 다 쪽이 외래 키를 가진다.
  • 다 쪽인 @ManyToOne은 항상 연관관계의 주인이 되므로 mappedBy를 설정할 수 없다.

5.6 양방향 연관관계의 주의점

  • 연관관계의 주인에는 값을 입력하지 않고 주인이 아닌 곳에만 값을 입력하는 것을 많이 실수한다. (디비에 외래 키 값이 정상적으로 저장되지 않을 때 의심)

5.6.1 순수한 객체까지 고려한 양방향 연관관계

  • 객체 관점에서 양쪽 방향에 모두 값을 입력해주는 것이 가장 안전하다.
  • 양쪽 방향 모두 값을 입력하지 않으면 JPA를 사용하지 않는 순수한 객체 상태에서 심각한 문제 발생 가능성이 있다.
  • 양쪽에 연관관계를 설정하면 순수한 객체 상태에서도 동작하며 테이블 외래 키도 정상 입력된다.

5.6.2 연관관계 편의 메소드

  • 양방향 관계에서 두 코드는 하나인 것처럼 사용하는 것이 안전
  • setTeam() 메서드를 만들어 하나로 양방향 관계를 모두 설정하도록 하는 메서드를 지칭

5.6.3 연관관계 편의 메서드 작성 시 주의사항

  • 연속으로 여러 팀을 지정할 수 있으므로 지정을 할 때 기존 팀과 회원의 연관관계가 있는지 판단하여 있다면 연관관계를 삭제하는 코드를 추가해야한다.

5.7 정리

  • 단방향 매핑과 비교해서 양방향 매핑은 복잡
  • 연관관계의 주인 설정 및 두 개의 단방향 연관관계를 양방향으로 만들기 위해 로직 관리도 중요
  • 연관관계가 하나인 단방향 매핑은 언제나 연관관계의 주인이다.
  • 양방향은 이러한 단방향에 주인이 아닌 연관관계를 하나 추가했을 뿐이다.
  • 결국 단방향과 비교해서 양방향의 장점은 반대방향으로 객체 그래프 탐색 기능이 추가된 것 뿐

5.8 연관관계의 주인을 정하는 기준

  • 단방향은 항상 외래 키가 있는 곳은 기준으로 매핑하면 됨
  • 양방향의 주인을 정할때 비즈니스 로직상 더 중요하다고 연관관계의 주인으로 선택하면 안됨
  • 단순히 외래 키 관리자 정도의 의미만 부여해야 함
  • 회원과 팀에 예제에서는 회원이 비즈니스 로직상 더 중요한 것 같아 회원이 주인이 되는 것이 이상한 느낌이 들지 않지만 대상을 바꾸어 자동차와 바퀴를 예로 들면 바퀴가 외래 키가 있는 다 쪽이다.
  • 즉, 바퀴가 연관관계의 주인이 되는 것이다.
  • 연관관계의 주인은 외래키의 위치와 관련해서 정해야지 비즈니스 중요도로 접근하면 안된다

댓글