자바 ORM 표준 JPA 프로그래밍 - 김영한
책 내용을 정리한 내용입니다.
챕터5 - 연관관계 매핑 기초
5.3 양방향 연관관계
5.4 연관관계의 주인
5.5 skip
5.6 양방향 연관관계의 주의점
5.7 skip
양방향 연관관계 ? 관계를 맺는 객체가 서로에 대한 접근이 가능한 관계
public class Member {
@Id
private Long id;
private String userName;
@ManyToOne
private Team team;
}
public class Team {
@Id
private Long id;
private String name;
@OneToMany(mappedBy = "team")
private List<Member> members;
}
@OneToMany 의 속성에는 mappedBy 속성이 있다. 해당 속성은 관계의 주인을 설정하는 속성이다.
JPA 에서는 두 객체 연관관계 중 하나를 정해서 테이블의 외래키를 관리해야하고 관리하는 쪽을 연관관계의 주인 이라고 한다.
(주인이 아닌쪽에서 mappedBy 속성을 사용해 주인을 지정한다)
연관관계의 주인에게는 값을 입력하지 않고 주인이 아닌 곳에만 값을 입력하면
데이터베이스에 반영되지 않는다.
@Transactional
public void save(){
Member member1 = new Member(1l, "member1");
em.persist(member1);
Member member2 = new Member(2l, "member2");
em.persist(member2);
Team team1 = new Team(1l, "team1");
team1.getMembers().add(member1);
team1.getMembers().add(member2);
em.persist(team1);
}
양방향 연관관계는 결국 양쪽 다 신경 써야함으로 연관관계를 수정하는 부분은 두 쪽 모두 수정이 일어날 수 있도록 로직을 만들어 준다.
/*
순수한 객체 연관관계를 고려하지 않는 경우
테이블에는 관계가 생성되지만
객체는 모르는 상태가 된다.
*/
Team team1 = new Team(1l, "team1");
em.persist(team1);
Member member1 = new Member(1l, "member1");
member1.setTeam(team1);
em.persist(member1);
Member member2 = new Member(2l, "member2");
member2.setTeam(team1);
em.persist(member2);
List<Member> members = team1.getMembers();
System.out.println("size : " + members.size()); // 0 출력
-----------------
// setTeam 양방향 관계를 모두 설정하는 연관관계 편의메소드로 변경해보자.
public void setTeam(Team newTeam) {
this.team = newTeam;
newTeam.getMembers().add(this);
}
--> System.out.println("size : " + members.size()); // 2 출력