양방향 매핑은 두 객체가 서로 참조해야 하는 상황에서 정의하는 연관관계 방식이다.
실제로는 각각의 단방향 매핑이 존재하는 것이며 이를 합쳐 양방향을 의미한다.
양방향 매핑을 할 때에는 아래와 같이 반드시 한쪽의 객체에 MappedBy 옵션을 설정해야 한다.
Member.java
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
private int age;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
… Getter, Setter 생략
}
Team.java
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<Member>();
… Getter, Setter 생략
}
만약 양방향 매핑을 적용한다면 Member 객체뿐만 아니라 Team 객체도 members 필드를 통해 MEMBER 테이블에 접근이 가능해지기 때문에 혼란이 생길 수 있다.
만약 Member 객체와 Team 객체가 서로 MEMBER 테이블의 데이터 값을 변경하려 한다면 무결성을 해칠 가능성도 생길 것이다.
그렇기 때문에 두 객체중 하나의 객체만 테이블을 관리할 수 있도록 정하는 것이 MappedBy 옵션인 것이다.
예제에서는 Team 객체에 MappedBy가 적용되어 있는 것을 볼 수 있는데 이 경우에는 Team 객체는 MEMBER 테이블을 관리할 수 없고 Member 객체만이 권한을 받고 주인이 아닌 쪽은 읽기(조회)만 가능해진다. 즉, MappedBy가 정의되지 않은 객체가 주인(Owner)가 되는 것이다.
일반적으로 외래키를 가진 객체를 주인으로 정의하는 것이 좋다.(예제도 외래키를 가진 Memeber 객체가 주인이 된 것이다.)