ecsimsw

JPA / 연관관계 매핑 / 양방향 매핑 / MappedBy 본문

JPA / 연관관계 매핑 / 양방향 매핑 / MappedBy

JinHwan Kim 2020. 6. 26. 06:36

"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. 설계는 단방향으로 하되, 반대로 접근이 필요해진 곳에 양방향을 추가하는 식으로 코드를 작성한다. 

   

 

  

 

  

 

Comments