JAVA/JPA
연관관계의 주인
gracelove91
2020. 1. 27. 00:53
연관관계의 주인
public class Member {
@ManyToOne
@JoinColumn(name = "team_id")
private Team team;
...
}
이렇게만 있어도 member.getTeam()
으로 객체그래프를 탐색할 수 있다.
하지만 반대쪽인 Team
객체에서는 List<Member> members
등과 같은 필드가 없기 때문에 Team
에서 Member
객체를 탐색할 수 없다. 추천하지는 않지만 아래와 같이 Team
에서도 Member
를 탐색할 수 있게끔 양방향관계를 갖고있다고 생각해보자.
public class Team {
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
...
}
엄밀히 말해서 엔티티에서는 양방향 관계란 있을 수 없다.
위와 같은 코드는 단방향관계가 두개인 것이다.
- member.getTeam();
- team.getMembers();
반면 DB에서는 테이블 외래키 하나만으로 양방향 연관관계를 맺을 수 있다.
이처럼 엔티티는 단방향 연관관계 두개, 테이블은 양방향 연관관계 하나로 패러다임의 불일치가 발생하게 된다.
이러한 차이로, JPA에서는 두 객체 연관관계중 하나를 정해서 테이블의 외래키를 관리하게 되는데 이것을 연관관계 주인이라 한다.
규칙
- 연관관계의 주인만이 DB연관관계와 매핑되고, 외래키를 관리(등록,수정,삭제) 할 수 있다.
- 반면 주인이 아닌 쪽은 읽기만 가능하다.
- 주인은
mappedBy
속성을 사용하지 않는다 - 주인이 아니라면
mappedBy
속성을 사용해서 속성의 값으로 연관관계 주인을 지정한다. - 위와 같은 코드에선 연관관계가 두개 나타난다.
- 회원 -> 팀 (Member.team)
- 팀 -> 회원 (Team.members)
- 연관관계의 주인은 외래키가 있는 곳이다.
- 회원테이블이 외래키를 가지고있으므로 Member.team이 주인이된다.
- 반대로 주인이 아닌 Team.members에서는 mappedBy="team" 옵션을 사용해서 주인이 아님을 설정한다.
- mappedBy의 값인 "team" 은 연관관계의 주인인 Member엔티티의 team 필드를 말한다.
결론
- DB는 일대다 관계에서 '다' 쪽에 외래키가 위치한다.
- 따라서 연관관계의 주인은 '다' 쪽이다
- 곧 '다' 쪽이 연관관계의 주인이다.
- 그러므로 '일'쪽에서 mappedBy로 연관관계의 주인이 아님을 명시하고, 그 값으로는 연관관계 주인인 엔티티의 필드를 명시해준다.