JPA 양방향 매핑

2021-02-03

JPA를 공부하면서 정리를 한 내용들 입니다.

-참고 김영한 개발자님 : [토크ON세미나] JPA 프로그래밍 기본기 다지기 - 양방향 매핑 T아카데미

5강. JPA 양방향 매핑

1.양방향 매핑

(반대 방향으로 객체 그래프 탐색)

@Entity
// 조회
Team findTeam = em.find(Team.class, team.getId());

// 역방향 조회
int memberSize = findTeam.getMembers().size();

2.연관관계 주인과 mappedBy

  • mappedBy는 처음에는 “왜 필요한가?” 처럼 이해하기 어렵습니다.
  • 객체와 테이블간에 연관관계를 맺는 차이를 이해해야 합니다.

3.객체와 테이블이 관계를 맺는 차이

객체 연관관계

* 회원 -> 팀 연관관계 1개 (단방향)
* 팀 -> 회원 연관관계 1개 (단방향)
  • 객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개 입니다.
  • 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 합니다.

테이블 연관관계

* 회원 <-> 팀 연관관계 1개 (양방향)
  • 테이블은 외래 키 하나로 두 테이블의 연관관계를 관리합니다.
  • 외래 키 하나로 양방향 연관관계 가집니다.(양쪽으로 조인할 수 있다.)
SELECT *
FROM MEMBER M
JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID

SELECT *
FROM TEAM T
JOIN MEMBER M ON T.TEAM_ID = M.TEAM_ID

4. 객체의 양방향 관계에서 문제점

(둘 중 하나로 외래키를 관리)

예를 들어 Member 객체에서 Team 객체의 값을 변경시키거나,

Team 객체에서 members에 member를 추가하는 등의 변화가 양쪽에서 일어난다면

어느쪽을 신뢰해야 하는가?

그래서 둘 중 하나로 외래키를 관리해야 합니다.

즉, 한 쪽을 연관관계의 주인으로 만들어주고 나머지 한쪽을 조회만 하도록 하는 것 입니다.

5.연관관계의 주인(Owner)

양방향 매핑 규칙

  • 객체의 두 관계 중 하나를 연관관계의 주인으로 지정합니다.
  • 연관관계의 주인만이 외래키를 관리합니다. (등록, 수정)
  • 주인이 아닌 쪽은 읽기만 가능합니다.
  • 주인은 mappedBy 속성 사용 X
  • 주인이 아니면 mappedBy 속성으로 주인 지정합니다.

6.누구를 주인으로?

  • 외래키가 있는 곳을 주인으로 정합니다.
  • 권장하는 것은 단방향으로 설계를 끝내고 개발하면서
    양방향이 필요한 부분이 생기면 코드를 추가하는 방식을 권합니다.

  • 그러나 순한참조로 인해 양방향보다 단방향이 좋습니다.
  • 처음 설계에서는 단방향으로 진행하고 나중에 양방향으로 진행하는 것이 좋습니다.

7.양방향 매핑시 가장 많이하는 실수

연관관계의 주인에 값을 입력하지 않는 것.

Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setName("member1");

//역방향(주인이 아닌 방향)만 연관관계 설정
team.getMembers().add(member);
em.persist(member);

이 경우, TEAM_ID가 null이 됩니다.

현업에서는 그냥 양쪽 모두 값을 입력하면 됩니다. 객체지향 관점에서도 양쪽 모두 값을 입력하는 것이 맞습니다.

8.양방향 매핑의 장점

  • 단방향 매핑만으로도 이미 연관관계 매핑은 완료됩니다.
  • 양방향 매핑은 반대 방향으로 조회(객체 그래프 탐색) 기능이 추가된 것 뿐입니다.
  • JPQL에서 역방향으로 탐색할 일이 많습니다.
  • 단방향 매핑을 잘하고 양방향 매핑은 필요할 때 추가하면 됩니다. (테이블에 영향 없음)