JPA

JPA_연관 관계 매핑

EJUN 2023. 9. 23. 22:09

JPA에서 대부분의 엔티티가 서로 관계를 맺고 있는 걸 확인할 수 있다.

연관관계 매핑이란?

객체의 참조와 테이블의 외래키를 매핑하는 것을 의미

 

연관관계 매핑 시 고려사항
1. 연관관계의 주인
2. 단방향, 양방향
3. 다중성

우선 그 전에 연관관계 주인에 대해 알아야 양방향관계에 대해서도 알 수 있으니 먼저 설명하겠다.

연관관계의 주인

  • 테이블은 외래키 하나로 두 테이블이 연관관계를 맺음
  • 객체 양방향관계는 A → B, B → A처럼 참조가 2군데 있음, 사실상 단방항관계가 2개 있는거
  • 객체 양방향 관계는 참조가 2군데 있는데, 둘 중 외래키를 관리할 테이블을 지정해야함
    • 연관관계의 주인 → 외래키를 관리하는 참조(주로 Many쪽에 있음)
    • 주인의 반대편 → 외래키에 영향을 주지 않음, 단순 조회만 가능
    • mappedBy를 통해 연관관계의 주인 필드를 선택함. mappedBy가 선언되지 않은 객체가 주인임.

mappedBy예시

연관관계 주인을 지정해 줘야 하는 이유?
JPA의 혼란을 방지하기 위해서이다.
public class Order{
	...
@OneToMany(mappedBy = "order",cascade = CascadeType.ALL)
    private List<OrderItem> orderItems=new ArrayList<>();
 }
public class OrderItem{
	...
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "order_id")
    private Order order;
}

 

이러한 관계가 있을 때 주문을 넣을 때 order객체의 메소드를 이용해서 넣는건지,
orderItems의 객체를 넣을지를 JPA입장에선 모호한입장이기 때문에 연관관계의 주인을 맺어줌
따라서, 위의 코드에서는 OrderItem이 주인이기 때문에 Order의 orderItems를 통해 값을 넣어도 DB에는 반영이 되지않고 조회만 가능

 


단방향 vs 양방향

단방향 -> 두 객체 사이에 하나의 객체만 참조용 필드를 갖고 참조하는 것

양방향 -> 두 객체 모두가 참조용 필드를 가지고 참조하는 것

  • 사실상 객체상에서만 양방향이지만 DB상에서는 각각의 테이블이 단방향 참조를 하고 있는 것.
그렇다면 어떤 방향을 선택하는 것이 좋을까?
우선 양방향매핑을 정말 잘 이해하고 잘 쓸 수 있는 것이 아니라면 사용하지 않는 것을 추천함

이유는?
객체 상에서 굉장히 복잡해질수 있기 때문!
만약 member객체가 board와 양방향매핑인데 board는 또 comment와 양방향관계인 경우,
member를 통해 board를 조회할 때 다른 불필요한 엔티티까지도 조회를 하기 때문에 가급적 단방향매핑을 추천함!!

다중성

1. 다대일: @ManyToOne

다대일 단방향

N : 1 관계 단방향

  • 가장 많이 사용하는 연관관계

다대일 매핑 예시

다대일 양방향

N : 1 관계 양방향

양방향을 의미하는데 양방향인 경우에는 위에서 설명한 외래키(FK)를 관리할 연관관계의 주인이 필요함

다대일 양방향은 FK가 있는 쪽이 연관관계의 주인이고, 양방향이기 때문에 양쪽을 서로 참조하도록 함

 

2. 일대다: @OneToMany

일대다 단방향

1 : N 단방향

  • 일대다 단방향은 꼭 @JoinColumn을 사용해야함.
    • 만약 사용하지 않으면 조인 테이블 방식을 사용해야하는데 이는 중간에 테이블을 하나 추가해야하므로 성능에 좋지 않음
더보기

일대다 단방향의 단점

1. 엔티티가 관리하는 외래 키가 다른 테이블에 있음(FK는 Many쪽에 존재하기 때문)

2. 연관관계 관리를 위해 추가로 UPDATE SQL 실행

일대다 양방향

일반적으로 이러한 매핑은 존재하지 않고, 다대일 양방향인 경우에 사용

 

3. 일대일: @OneToOne

  • 일대일 관계에서 단방향관계는 JPA에서 지원을 하지 않음

1 : 1 양방향

  • 일대일 관계는 그 반대도 일대일 관계
  • 주 테이블이나 대상 테이블 중에 외래키 선택 가능
    • 주 테이블에 외래키
    • 대상 테이블에 외래키
  • 외래키에 DB 유니크 제약조건 추가
  • 외래키가 있는 곳이 연관관계의 주인
    • 반대편은 mappedBy적용
  • 대상테이블에 외래키 단방향정리
    • 단방향 관계는 JPA 지원X, 양방향 관계는 지원
  • 단방향에서의 FK는 더 많이 사용되는 엔티티에 선언
주 테이블에 외래 키
  • 주 객체가 대상 객체의 참조를 가지는 것 처럼 주 테이블에 외래 키를 두고 대상 테이블을 찾음
  • JPA 매핑 편리
  • 장점: 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인 가능
  • 단점: 값이 없으면 외래 키에 null 허용
대상 테이블에 외래 키
  • 대상 테이블에 외래 키가 존재
  • 장점: 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테이블 구조 유지
  • 단점: 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨 

1:1예시

위와 같은 경우가 있을 때,
주 테이블(Member)에 외래 키가 있는 경우는 Member테이블만 조회해서 Locker FK가 있는지 확인해서 있으면 프록시 객체를 호출하면 되기 때문에 즉시로딩이 가능한데,
만약 대상테이블(Locker)에 외래키가 있는 경우는 Member테이블만 조회해서는 Locker가 있는지 확인이 불가하기 때문에 무조건 즉시 로딩을 해야함

'JPA' 카테고리의 다른 글

JPA_DataSource  (1) 2023.10.17
JPA_값 타입  (0) 2023.10.05
JPA_프록시와 연관관계관리  (0) 2023.09.26
JPA_영속성 컨텍스트 & 객체와 테이블  (0) 2023.09.19