ecsimsw
JPA / 연관관계 매핑 / 양방향 매핑 / MappedBy 본문
"T아카데미 / JPA 프로그래밍 기본기 다지기 - 김영한 " 강좌를 듣고 정리한 글입니다.
양방향 매핑
이전 단방향 매핑 member - team의 구조에서 이번에는 team에서 member를 얻고 싶은 경우에는 어떻게 해야할까.
Team에 List members를 만들고, member의 team과 매핑하면 된다.
Member
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name="TEAM_ID")
private Team team;
}
Team
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<Member>();
}
@OneToMany로 team과 매핑하여 members 가져옴
Team에서 members 얻기
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("memberA");
member.setTeam(team);
em.persist(member);
em.flush(); // db에 쿼리를 다 보냄
em.clear(); // 캐시 비움
// 만약 위과정이 없다면 바로 find시 team에 members가 적용이 안되어 있음
List<Member> members = findTeam.getMembers();
MappedBy
근데 MappedBy는 왜 있을까. 그냥 team이랑 members랑 양쪽으로 관리하는 것과 다를까?
테이블의 연관 관계는 양방향 관계가 된다. TEAM_ID를 외래 키로 해서 양방향 조회가 가능하다.
Member의 Team을 알고 싶으면 TEAM_ID로 TEAM에 조인해서 MEMBER 테이블에 붙이면 되고,
TEAM에 속한 Member를 알고 싶으면, TEAM_ID로 MEMBER에 조인해서 TEAM 테이블에 붙이면 되는 것이다.
반면 객체의 연관 관계는 사실 두개의 단방향으로 이루어진다.
따라서 엔티티를 양방향 매핑으로 설정하면 객체의 참조는 둘인데 반해, 테이블은 하나의 외래 키 만을 사용하게 된다.
만약 teamA.getMembers().add(memberA)과 memberA.setTeam(teamB)가 호출된다면 어떻게 처리할 것인가.
teamA에 memberA를 넣되 memberB는 teamB다? 또는 Team에서 members의 team 값을 바꾸도록 한다?
jpa가 내린 규칙은 간단하다.
한쪽에서만 테이블의 외래키를 바꿀 수 있도록 하는 것이다. 그 관리자를 '연관관계의 주인' 이라고 정한다.
mappedBy는 어떤 객체가 주인인지를 표시하는 어노테이션 인 것이다.
mappedBy(team)이면, team을 갖고 있는 Member가 team(FK)의 주인이 되는 것이다.
- 오직 주인만 FK를 관리한다.
- 주인이 아닌 곳에서는 mappedBy로 주인을 명시해야한다.
Owner
그럼 주인은 어떻게 정하는 게 좋을까. 김영한 강사님의 팁은 다음과 같다.
1. FK가 있는 곳을 주인으로 한다.
2. 객체의 개념에 따라서 Team의 members에도 member를 추가하고, member에도 team을 추가하는 식으로 양쪽 다 삽입하는 것도 실수를 줄이기 위한 방법이다.
3. 설계는 단방향으로 하되, 반대로 접근이 필요해진 곳에 양방향을 추가하는 식으로 코드를 작성한다.
'Database > JPA, ORM' 카테고리의 다른 글
JPA / 영속성 컨텍스트 / 1차 캐시 / 쓰기 지연 (0) | 2020.06.28 |
---|---|
JPA / 영속성 컨텍스트 / 엔티티 생명 주기 (0) | 2020.06.28 |
JPA / 연관 관계 매핑 / 단방향 매핑 (0) | 2020.06.26 |
JPA / 기본 키 매핑 (0) | 2020.06.26 |
JPA / 필드와 컬럼 매핑 (0) | 2020.06.25 |