[JPA] 연관 관계

1

JPA

목록 보기
1/16
post-thumbnail

연관 관계란 ?

연관 관계란 객체의 참조와 테이블의 외래 키를 매핑시키는 것이라고 보면 편하다. 연관 관계는 크게 3가지로 나누어 볼 수 있다.

  • 객체 사이의 방향
  • 연관 관계를 가진 객체의 주인
  • 다중성

자세히 알아보도록 하자


객체사이의 방향

연관 관계에서 객체사이의 방향은 단방향과 양방향으로 이루어져있다. 단방향은 말 그대로 한 방향으로 흐르는것이다. 양방향은 한번에 흐르는 참조가 있는 것 같지만 실은 단방향 2개가 모여서 만들어진 것이 양방향이다.

  • 단방향 (A -> B) or (B -> A)
  • 양방향 (A -> B) and (B -> A)

2가지 방향성이 있지만 양방향은 단방향으로도 흐를수 있으므로 양방향만 쓰면 되지 않는가? 라는 생각이 들 수도 있다.

하지만 무조건 양방향으로 설계하는것은 좋지 않다.
그 이유는 객체 입장에서 양방향 매핑을 했을때 사용자의 입장에서는 엔티티들과 매우 복잡한 관계를 가질수 밖에 없기 때문이다. 이렇게 연관 관계에서 양방향을 남발한다면, 나중에 다시 자신이 설계한 관계형 데이터베이스를 봐도 이해할 수 없는 아이러니한 상황이 발생할 수 있다.

연관 관계에서의 주인

2개의 객체가 양방향 연관 관계를 가질 때 연관 관계에서의 주인을 정해줘야 한다.

연관 관계에서의 주인이라 하면, 연관 관계의 주인을 지정 하는 것은 두 단방향 관계(A→B, B→A)중, 제어의 권한(CRUD)을 갖는 객체가 어느 객체인지 JPA에게 알려주는 것이라고 보면된다.

연관 관계에의 주인을 정해주어야 하는 이유는 정해져 있다. A의 데이터를 수정한다고 가정하였을 때 A의 데이터를 수정하는 방식도 있지만, B의 데이터를 수정하는 방식도 틀리지 않았기에 JPA의 입장에서는 매우 혼란스러울 것이다. 따라서 연관 관계에서의 주인은 명확하게 정의 해주어야 한다.


다중성

  • 일대다(1:N)
  • 다대일(N:1)
  • 다대다(N:M)

연관 관계는 대칭성을 가진다.

  • 일대다(1:N) ↔ 다대일(N:1)
  • 일대일(1:1) ↔ 일대일(1:1)
  • 다대다(N:M) ↔ 다대다(N:M)

다대일(N:1) 양방향

다대일 양방향으로 만드려면 @OneToMany를 추가해서 양방향 매핑이 되었으므로 연관 관계의 주인을 mappedBy를 사용해서 Member로 지정해준다.

package jpabook.jpashop.domain;

import lombok.Getter;
import lombok.Setter;
import org.apache.tomcat.jni.Address;

import javax.persistence.*;
import javax.persistence.criteria.Order;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@Setter
public class Member {

    @Id @GeneratedValue
    @Column(name = "member_id")
    public Long id;

    private String name;

    @Embedded
    private Address address;

    @OneToMany(mappedBy = "member") // 연관 관계의 주인 정하기
    private List<Order> orders = new ArrayList<>();

}

나머지 일대일(1:1), 일대다(1:N), 다대다(N:M)는 사용하지 않는것을 권장한다.

  • 일대일(1:1) : JPA에서는 아예 지원자체를 않으며, 논란의 여지가 많음(A에게 포린키를 줄 것인가, B에게 포린키를 줄 것인가)

  • 일대다(1:N) : 일대다(1:N) 단방향 연관 관계 매핑보다 다대일(N:1) 양방향 연관 관계를 매핑이 유지보수에 더 좋은 모습을 보여줌

  • 다대다(N:M) : 다대다 관계에서는 객체 사이에 조인 중간 테이블이 숨겨져 있기 때문에 복잡한 조인의 쿼리가 발생하는 경우가 생길 수 있음


0개의 댓글