[5장] 연관관계 매핑 기초

1.단방향 연관관계

  • 다대일(N:1) 단방향 연관관계
    • 회원이 하나의 팀에만 소속 가능
    • 회원과 팀은 다대일 관계
      • 객체 연관관계 기준
        • 회원은 Member.team 필드로 팀 객체와 연관관계
        • 회원은 Member.team 필드로 팀 조회 가능/ 팀은 회원 조회 불가
      • 테이블 연관관계 기준
        • 회원 테이블은 team_id 외래키로 팀 테이블과 연관관계
        • 회원 테이블/팀 테이블은 양방향 관계
          • team_id 외래키로 회원 JOIN 팀/팀 JOIN 회원 모두 가능
      • 객체 연관관계 vs 테이블 연관관계
        • 참조를 통한 객체 연관: 언제나 단방향
          • 객체 간 연관관계를 양방향으로 만드려면 반대쪽에도 필드 추가 필요
            • 서로 다른 단방향 연관 관계 2개로 처리 / 양방향 연관 관계 X
          • 테이블은 외래키 하나로 양방향 JOIN 가능
        • 객체는 참조(주소)로 연관관계 맺음
          • 객체의 연관관계: 단방향
        • 테이블은 외래키로 연관관계 맺음
          • 외래키 사용 테이블의 연관관계: 양방향

 

1-1. 순수한 객체 연관관계

객체 그래프 탐색: 참조를 사용해서 객체 연관관계 탐색 가능

예시)

  • 회원 클래스 내에 팀 클래스의 참조를 보관
  • 회원 1, 2를 팀 1에 소속시킴(INSERT)
  • 회원 1이 속한 팀1 조회 가능

 

1-2. 테이블 연관관계

조인(JOIN): DB는 외래 키로 연관 관계 탐색 가능

예시)

  • 회원 테이블의 team_id(외래 키)로 회원 1 & 팀 테이블의 팀 1 조회 가능
  • 팀 테이블에서 회원의 team_id로 팀 1 & 팀에 속한 회원 조회 가능

 

1-3. 객체 관계 매핑

객체 연관관계: 회원 객체의 Member.team 필드 사용

테이블 연관관계: 회원 테이블의 team_id 외래 키 컬럼 사용

  • @ManyToOne: 다대일 매핑 정보 / N:1 연관관계 매핑시 필수
  • @JoinColumn(name="team_id"): 외래 키 매핑시 필수 / name 속성으로 외래 키 이름 지정
    • 생략시 기본 전략 사용
    • 기본 전략: 필드명 + _ + 참조 테이블 컬럼명 / ex) team_team_id

 

2-1. 저장

  • 회원 엔티티는 팀 엔티티를 참조/저장
  • JPA → 참조한 팀의 식별자를 외래 키로 사용해서 등록 쿼리 생성

2-2.조회

  • 연관관계 엔티티 조회 방법
    • 객체 그래프 탐색
      • 객체를 통해 엔티티를 조회
    • 객체 지향 쿼리 사용(JPQL)
      • SQL처럼 JOIN 지원
      • :로 시작하는 부분 → 파라미터를 바인딩받는 문법
      • 엔티티 객체를 대상으로 하고, SQL보다 간결

2-3. 수정

  • em.update 같은 메소드 X
  • 엔티티의 값 변경시 → 트랜잭션 커밋할 때 플러시 발생 → 변경 감지로 DB에 자동 반영
  • JPA가 자동으로 처리함

 

2-4. 연관관계 / 연관 엔티티 제거

  • 연관관계 null로 설정시 연관관계 제거됨
  • 연관 관계 제거후 연관 엔티티 삭제
    • 외래 키 제약 조건으로 DB에서 오류 발생

 

3. 양방향 연관관계

  • 회원에서 팀으로 접근/ 팀에서 회원으로 접근 가능
  • 객체 연관관계
    • 회원 → 팀: 다대일 관계
    • 팀 → 회원: 일대다 관계
    • 일대다 관계: 여러 건과 연관관계 가능 → 컬렉션 사용
  • 테이블 관계
    • DB 테이블: 외래 키 하나로 양방향 조회 가능
    • DB에 추가할 내용 없음

 

4. 연관관계의 주인

  • @OneToMany에 mappedBy 속성이 필요한 이유
    • 객체에는 양방향 연관 관계 X
    • 서로 다른 단방향 연관관계 2개를 로직으로 묶어서 양방향 처럼 보이게 함
    • DB 테이블은 외래 키 하나로 양쪽 서로 JOIN 가능
  • DB는 외래 키 하나로 두 테이블의 연관관계 관리
  • 엔티티를 단뱡향 매핑 → 참조 하나만 사용
  • 엔티티 양방향 연관관계 설정시: 객체 참조는 둘 / 외래 키는 하나 → 둘 사이 차이가 발생
    • JPA → 두 객체 연관관계 중 하나를 정해 테이블의 외래 키를 관리하게 함 : Owner(연관관계의 주인)
    • 연관관계의 주인만 DB 연관관계와 매핑/외래 키 관리(등록. 수정. 삭제) 가능: 외래 키 관리자
      • 주인은 mappedBy 속성 미사용
    • 주인 X → 읽기만 가능
      • 주인이 아니면 mappedBy로 연관관계 주인 지정

 

5. 양방향 연관관계의 주의점

  • 주인에는 값 입력 X / 주인이 아닌 곳에만 값: DB에 외래 키 미저장시 체크 필요
  • 객체 관점에서 양쪽 방향에 모두 값을 입력해주는게 제일 안전
    • 미입력시: JPA 미사용 객체 상태에서 문제 발생
  • 연관관계 변경시 기존 데이터와의 연관관계를 제거하는 코드 추가 필요
  • 객체에서 양방향 연관관계 사용하려면 로직 견고 필수!

 

6. 단방향 vs 양방향

  • 연관관계가 하나인 단방향 매핑: 언제나 연관관계의 주인
    • DB 테이블과 객체의 연관관계 매핑은 이미 완료
  • 양방향: 단방향 매핑에 주인이 아닌 연관관계를 하나 추가한 것
    • 반대방향으로 객체 그래프 탐색 기능이 추가
    • 객체에서 양쪽 방향 모두 관리 필요
    • 무한 루프에 유의해야함

'책 스터디 정리 > JPA ORM 스터디' 카테고리의 다른 글

[7장] 고급 매핑  (0) 2023.05.09
[6장] 다양한 연관관계 매핑  (0) 2023.05.02
[4장] 엔티티 매핑  (0) 2023.04.18
[3장] 영속성 관리  (0) 2023.04.11
[1장] JPA 소개  (0) 2023.04.04