[자바 ORM 표준 JPA 프로그래밍] 5. 연관관계 매핑 기초

서요이·2022년 11월 7일
0
post-thumbnail

5. 연관관계 매핑 기초

연관관계가 필요한 이유

객체지향 설계의 목표
자율적인 객체들의 협력 공동체를 만드는 것

객체를 테이블에 맞추어 데이터 중심으로 모델링하면 협력 관계를 만들 수 없음

@Entity
public class Member {
	...
	@Column(name = "TEAM_ID")
	private Long teamId;
	...
}

연관된 테이블을 찾을 때
테이블 - 외래 키로 조인 vs 객체 - 참조 사용

단방향 연관관계

객체 지향 모델링
객체의 참조와 테이블의 외래 키를 매핑

@Entity
public class Member {
	...
	@ManyToOne
	@JoinColumn(name = "TEAM_ID")
	private Team team;
	...
}
Member.findMember = em.find(Member.class, member.getId());
Team findTeam = findMember.getTeam();

양방향 연관관계와 연관관계의 주인

양방향 매핑

@Entity
public class Member {
	...
	@ManyToOne
	@JoinColumn(name = "TEAM_ID")
	private Team team;
	...
}
@Entity
public class Team {
	...
	@OneToMany(mappedBy = "team")
	List<Member> members = new ArrayList<Member>();
	...
}

객체와 테이블이 관계를 맺는 차이

  • 객체 연관관계 = 2개
    회원 →팀 (단방향) + 팀 → 회원 (단방향)
  • 테이블 연관관계 = 1개
    회원 ↔ 팀 (외래 키 하나로 양방향)

연관관계의 주인 (Owner)

  • 객체의 두 관계 중 하나를 연관관계의 주인으로 지정
  • 연관관계의 주인만이 외래 키를 관리(등록, 수정)
  • 주인 - mappedBy X, 주인이 아님 - mappedBy
  • 외래 키가 있는 곳(Many)을 주인으로 지정 (비즈니스 로직 기준 X)

양방향 매핑 시 가장 많이 하는 실수

Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setName("member1");

// 역방향(주인이 아닌 방향)만 연관관계 설정
team.getMembers().add(member);
em.persist(member);

→ 연관관계 주인에 값 입력되지 않음

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);

양방향 매핑 시 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정

연관관계 편의 메소드 생성 (둘 중 하나만 생성)

// Member에서 메소드 생성
public void changeTeam() {
	this.team = team;
	team.getMembers().add(this);
}
// Team에서 메소드 생성
public void addMember(Member member) {
	member.setTeam(this);
	members.add(member);
}

양방향 매핑 시 무한 루프 조심 (toString(), lombok, JSON 생성 라이브러리)

양방향 매핑 정리

  • 처음에는 단방향 매핑으로 설계하기 → 연관관계 매핑 완료
  • 양방향 매핑은 반대 방향으로 조회(객체 그래프 탐색) 기능이 추가된 것 뿐
  • JPQL에서 역방향으로 탐색할 때 추가
  • 최대한 단방향 매핑으로 하고 양방향은 필요할 때 추가(테이블에 영향 주지 않음)

0개의 댓글