단방향 연관관계
객체를 테이블에 맞추어 모델링 하기
//조회
Member findMember = em.find(Member.class, member.getId());
//연관관계가 없음
Team findTeam = em.find(Team.class, team.getId());
테이블 -> 외래키로 조인을 사용하여 연관된 테이블 찾음
객체 -> 참조를 사용하여 연관된 객체를 찾음
=> 객체와 테이블의 연관관계의 차이가 발생
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
private int age;
// @Column(name = "TEAM_ID")
// private Long teamId;
@ManyToOne // 다중성 설정
@JoinColumn(name = "TEAM_ID") // 외래키 칼럼 설정
private Team team;
em.persist(team)을 할 경우 영속성 컨텍스트에 team의 기본키가 세팅되어 있기 때문에, member.setTeam(team) 을 하면 자동으로 member에 teamId가 매핑됨
//팀 저장
Team team = new Team();
team.setName("TeamA");
em.persist(team);
//회원 저장
Member member = new Member();
member.setName("member1");
member.setTeam(team); //단방향 연관관계 설정, 참조 저장
em.persist(member);
Member findMember em.find(MEMBER.class, member.getId());
Team findTeam = findMember.getTeam();
양방향 연관관계와 연관관계의 주인 1 - 기본
객체와 테이블간에 연관관계의 차이
-> 테이블은 외래키를 사용해 조인하면 양방향 모두 서로 값을 알 수 있기 때문에 방향이라는것이 정해져 있지 않다.
-> 이에 반해 객체는 필드에 선언을 해야 하기 때문에 방향성을 지닌다.
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "team") //방향의 반대편 사이드에는 "team"이 걸려있다.
List<Member> members = new ArrayList<Member>();
…
}
양방향 연관관계는 사실 단방향 연관관계 2개가 묶인것이다.
위와 같이 양쪽에서 관리하게 된다면, 충돌문제가 발생할 수 있기 때문에
둘 중 하나로 외래키를 관리해야 한다
=> 그래서 나온것이 "연관관계의 주인"
연관관계의 주인
그렇다면 어느쪽을 주인으로 설정할 것인가???
=> 외래키가 있는 곳을 주인으로 정하자
테이블 연관관계를 보면
1:N 관계에서 N 방향 테이블에 외래키를 갖고 있다.
따라서 객체또한 N쪽에 연관관계의 주인을 지정해줘야 한다.
(무조건 이렇게 해야 한다 ! 는 아니지만 경험상 이렇게 하면 쉽게 할 수 있다)
양방향 연관관계와 연관관계의 주인 2 - 주의점, 정리
양방향 매핑시 연관관계의 주인에 값을 입력해야 한다
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
//역방향(주인이 아닌 방향)만 연관관계 설정
team.getMembers().add(member);
//연관관계의 주인에 값 설정
member.setTeam(team); //**
em.persist(member);
중요한것은 단방향 매핑만으로도 이미 연관관계 매핑이 완료되어야 된다.
(양방향은 단순히 그래프 탐색 기능을 추가해 준 것뿐이다)
public void addMember(Member member) {
member.setTeam(this);
members.add(member);
}
public void changeTeam(Team team) {
this.team = team;
team.getMembers().add(this);
}
JPAMain 코드에서
team.getMembers().add(member);
member.setTeam(team);
//순수 객체 상태를 고려해서 양쪽에 값을 입력해야 한다.
//하지만 둘 중 코드 하나를 잊어버릴수 있기 때문에, 편의 메서드를 사용하자
team.addMember(member);
//OR
member.changeTeam(team);
실전 예제 2 - 연관관계 매핑 시작
Reference
김영한 님 - 자바 ORM 표준 JPA 프로그래밍 - 기본편