Spring

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

se-mumu 2023. 6. 5. 02:51

섹션 5. 연관관계 매핑 기초

객체와 테이블의 연관관계

  • 테이블은 외래 키 조인을 사용해 연관된 테이블을 찾음
  • 객체는 참조를 사용해 연관된 객체를 찾음
  • 객체를 테이블에 맞추어 모델링하게 되면, 참조 대신 외래 키를 그대로 사용하게 됨
  • 외래 키 식별자를 직접 설정, 조회하기 때문에 객체 지향적인 방법이 아님

 

단방향 연관관계

  • 객체의 참조와 테이블의 외래 키를 매핑
@Entity
public class Member {

    // ...

    @ManyToOne // Member Entity가 Many, 매핑된 Team이 One
    @JoinColumn(name = "TEAM_ID")
    private Team team;
  • 연관관계 저장, 조회, 수정이 명확해짐
// 단방향 연관관계 설정, 참조 저장
member.setTeam(team);

// 참조를 사용해 연관관계 조회
Team findTeam = findMember.getTeam();

// 연관관계 수정 (회원에 새로운 팀 설정)
member.setTeam(newTeam);

 

양방향 연관관계

  • Team 엔티티에 Member 리스트를 추가하여 팀에 속해있는 회원들을 참조
@Entity
public class Team {

	// ...
    
    @OneToMany(mappedBy = "team")
    List<Member> members = new ArrayList<Member>(); // 리스트 초기화해주는 것이 관례
// 역방향 조회
int memberSize = findTeam.getMembers().size();

 

연관관계의 주인과 mappedBy

  • 객체의 양방향 연관관계는 사실 단방향 연관관계 2개로 이루어진 것
    • 회원 -> 팀 참조
    • 팀 -> 회원 참조
  • 반면 테이블은 외래 키 조인에 의한 연관관계 1개로 이루어짐 (방향 개념이 없음)
    • 회원 --- 팀 조인
  • 따라서 회원 -> 팀 참조, 팀 -> 회원 참조 둘 중 하나로 외래 키를 관리해야 함

양방향 매핑 규칙

  • 객체의 두 관계 중 하나를 연관관계의 주인으로 지정
  • 연관관계의 주인만이 외래 키를 관리(등록, 수정)하며 주인이 아닌 쪽은 읽기만 가능
  • 주인이 아닌 객체가 mappedBy 속성으로 주인 지정

누구를 주인으로 해야할까?

  • 외래 키가 있는 곳을 주인으로 정하기
    • 일대다 관계에서 '다'에 해당하는 테이블에 매핑된 객체
    • 즉 ManyToOne 속성을 쓰는 객체
    • 위의 예시에서는 Member 객체의 team이 연관관계의 주인이 됨

 

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

  • 연관관계의 주인에 값을 입력하지 않음
// 역방향(주인이 아닌 방향)만 연관관계 설정
team.getMembers().add(member);
  • DB에서 외래 키가 반영되지 않기 때문에 연관관계의 주인에 값 설정 필요
member.setTeam(team);
  • member에서 team을 설정하면, team의 members 리스트에 해당 멤버를 추가하지 않아도 JPA가 조회 시 외래 키 조인과 함께 쿼리를 날려서 members 리스트에 해당 멤버가 추가된 것을 확인할 수 있음
  • 그러나 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정할 것

연관관계 편의 메서드

  • member에서 team을 지정할 때, team의 members 리스트에 해당 member 객체가 추가되도록 함
// Member Entity
public void setTeam(Team team) {
	this.team = team;
	team.getMembers().add(this);
}
  • getter/setter 관례 때문에 setTeam에 코드를 추가하기 보다 비즈니스 로직을 담당하는 changeTeam 메서드를 만드는 것이 권장됨

양방향 매핑 시 무한 루프 조심

  • toString(), lombok, JSON 생성 라이브러리 사용 시, 양방향으로 매핑된 객체가 함수를 무한으로 호출하는 문제 발생

 

양방향 매핑 정리

  • 단방향 매핑만으로도 이미 연관관계 매핑은 완료
    • 처음에 단방향 매핑만으로 설계를 마칠 것
    • 그 다음, 양방향 매핑은 필요에 따라서 조회를 위해 추가
    • 객체 입장에서 양방향 매핑은 신경쓸 일이 많아져서 달가운 일은 아님
  • 연관관계의 주인을 정하는 기준
    • 비즈니스 로직을 기준으로 연관관계의 주인을 선택하면 안됨
    • 연관관계의 주인은 외래 키의 위치를 기준으로 정해야 함 (고민거리가 싹 사라진다고 하네요)

 

 

Reference

https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com