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에서 역방향으로 탐색할 일이 많습니다.
- 단방향 매핑을 잘하고 양방향 매핑은 필요할 때 추가하면 됩니다. (테이블에 영향 없음)