Framework | Library | Tool/Spring Data | JPA

JPA, 연관관계 매핑

주정용 2021. 9. 12. 22:51
728x90
  • RDB의 데이터들은 정규화 과정을 통해서 테이블 간 관계가 형성됨
  • JPA는 이러한 RDB의 관계를 객체를 통해서 표현해야함
  • 연관관계 매핑은 RDB 테이블 간 관계를 Java 객체로 표현하는 것
  • 연관관계 매핑을 통해서 불필요한 Join을 줄일 수 있고, 데이터 적재 시점을 결정할 수도 있음
  • 테이블의 관계는 항상 양방향, 객체의 관계는 방향성이 있기 때문에 이러한 특성을 고려해야함

연관관계 매핑 기준

  • 방향성

    • 객체는 방향성이 존재(단방향, 양방향)
    • 테이블은 항상 양방향
  • 다중성

    • N:1, 1:N, 1:1, N:M

@ManyToOne

  • 엔티티 간 N:1 관계를 표현
  • N인 엔티티에서 반대편 엔티티 객체를 표현할 때 사용
  • 주요 속성
    • optional
      • 연관 엔티티의 필수 여부
      • false --> 연관 엔티티가 필수
      • false라면 연관 엔티티와의 관계를 끊을 수 없음
    • fetch
      • 글로벌 페치 전략
      • Eager, Lazy
    • cascade
      • 영속성 전이 옵션
  • Join
    • 영속성 컨테이너는 기본적으로 Outer Join을 실행함
    • Inner Join을 실행하기 위해서 optional 값을 false로 설정

@OneToMany

  • 엔티티 간 1:N 관계를 표현
  • 1인 엔티티에서 반대편 엔티티 Collection을 표현할 때 사용
    • List
      • 순서대로 객체를 저장
      • 중복을 허용
    • Set
      • 객체의 순서를 보장하지 않음
      • 중복을 허용하지 않음
      • Set에 담길 엔티티는 컬렉션 특성상 equalshashCode를 재정의해야 함
      • lombok@EqualsAndHashCode를 사용할 경우, 순환참조를 방지하기 위해서 Collection 필드를 제외해야함
  • 주요 속성
    • @ManyToOne과 같은 속성을 사용
    • mappedBy
      • 연관관계의 소유자를 표현
      • 연관관계의 소유자는 외래키를 지닌 엔티티(테이블)
      • 연관관계의 소유자가 자신을 표현하는 필드명을 값으로 사용
  • 연관관계의 소유자
    • 객체지향과 RDB의 구조적 불일치를 해결하기 위한 방법
    • 양방향 연관관계에서는 외래키와 매핑된 참조변수를 연관관계의 소유자라고 함
    • 연관관계의 소유자만이 외래키에 대한 관리를 수행할 수 있고, 반대편은 읽기만 가능

@OneToOne

  • 엔티티 간 1:1 관계를 표현
  • 1:N 매핑 에너테이션과 속성은 거의 동일함
  • 부모키를 공유하는 1:1 매핑
    • 1:1 관계에서는 부모 테이블의 PK자식 테이블의 PK로 사용하는 경우도 있음
    • @MapsId를 통해서 부모 테이블의 PK를 자식 테이블의 FK이자 PK로 사용할 수 있음
    • @MapsId을 참조변수 위에 선언하는 것은 @JoinColumn으로 매핑한 FK를 PK로 사용하겠다는 의미

영속성 전이(Cascade)

  • 데이터의 lifecycle이 다른 데이터와 관련된 경우 Cascade 기능을 사용할 수 있음
  • @OneToMany@ManyToOne에서 설정
  • 영속성 전이를 위해서는 연관관계에 있는 엔티티가 반드시 영속성 컨테이너에 의해 managed인 상태여야 함
  • Cascade 속성 값
    • CascadeType.All
      • 아래의 모든 전이 기능을 포함
    • CascadeType.PERSIST
      • 엔티티가 컨테이너에 저장될 때 참조 엔티티도 저장
    • CascadeType.MERGE
      • 엔티티를 병합할 때 참조 엔티티도 컨테이너에 병합
    • CascadeType.REMOVE
      • 엔티티가 컨테이너에서 삭제될 때 참조 엔티티도 삭제
    • CascadeType.REFRESH
      • 엔티티를 갱신할 때 참조 엔티티도 DB로부터 갱신
    • CascadeType.DETACH
      • 엔티티를 분리할 때 참조 엔티티도 컨테이너에서 분리
  • 특정 상황에서 전이를 사용하고 싶지 않을 때에는 연관관계에 사용한 참조변수를 null로 설정한다

고아 제거 속성

  • 부모 엔티티와 연관관계에서 제외된 자식 엔티티를 삭제하는 기능
  • @OneToMany, @OneToOne에서 orphanRemovaltrue로 설정하면 제거 기능이 동작한다
    • 영향도를 고려하여 자식엔티티를 다른 엔티티와 공유하지 않을 때에만 적용한다
  • CascadeType.ALL과 orphanRemovel을 모두 사용하면 부모 엔티티과 자식 엔티티의 수명주기를 모두 관리할 수 있다

참고자료

JPA 퀵스타트, 채규태