모델링
아래 그림을 보면 객체에서 양방향으로 연관관계를 설정해도 테이블은 단방향과 차이점이 없다. 즉 테이블에서는 방향이라는 개념 없이 외래 키를 이용해서 조인하여 서로의 연관관계를 알 수 있다. 하지만 객체에서 Team이 Member를 참조하기 위해서는 Member의 list가 Team 객체 내에 존재해야 한다.
양방향 연관관계 코드
Member의 경우 단방향과 동일하다.
@Entity
public class Member {
...
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
...
}
Team에서는 List를 통해 Member를 참조하게 되고, 이때 mappedBy = "team"
을 통해 Member 객체 내의 Team team
과 매핑을 해줄 수 있다.
@Entity
public class Team {
...
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<Member>();
...
}
이를 통해 아래 코드와 같이 Team에서도 Member를 조회할 수 있다.
//조회
Team findTeam = em.find(Team.class, team.getId());
Member findMember = em.find(Member.class, member.getId());
//Team으로부터 Member정보 조회
int memberSize = findTeam.getMember().size();
//Member로부터 Team을 조회 후 Team에 속한 모든 Member조회
List<Member> members = findMember.getTeam().getMembers();
객체 연관관계 = 2개
테이블 연관관계 = 1개
객체의 양방향 연관관계
객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개이다. 즉 객체를 양방향을 참조하려면 단방향 연관관계를 2개 만들어야 한다.
테이블의 양방향 연관관계
테이블은 외래 키 하나로 두 테이블의 연관관계를 관리한다. 즉 양쪽으로 조인할 수 있다.
외래 키 관리
객체 관점에서는 2개의 단방향 연관관계가 존재하지만 테이블 상에서는 하나의 외래 키만 존재한다. 따라서 2개의 연관관계 중 하나가 이 외래 키를 관리해야 한다.
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
//역방향(주인이 아닌 방향)만 연관관계 설정
team.getMembers().add(member);
em. persist(member);
따라서 반드시 주인에 값을 입력해야 하고, 순수한 객체 관계를 고려해서 항상 양쪽 모두 값을 입력해야 한다.
...
//연관관계의 주인인 member에 값 설정
member.setTeam(team);
//team에도 연관관계 설정
team.getMembers().add(member);
...
Inflearn 김영한 님의 자바 ORM 표준 JPA 프로그래밍 - 기본편 : https://www.inflearn.com/course/ORM-JPA-Basic/dashboard