[JPA] 다양한 연관관계 매핑

2025. 7. 1. 15:37·DB Access/JPA
다양한 연관관계 매핑

다양한 연관관계 매핑

#JPA/기본


/연관관계 매핑시 고려사항 3 가지

  • /다중성 (N:M)
  • /단방향, 양방향: 테이블과 객체의 차이 고려!
  • /연관관계의 주인은 어디에?

/다대일 [N:1]

  • /다대일 단방향
  • /다대일 양방향
    • 연관관계 주인: FK 기준

/일대다 [1:N]

  • /일대다 단방향: 객체에서 연관관계 주인은 1쪽이지만, DB에서 FK는 다쪽에 있다.
    • 객체와 테이블의 차이 때문에 반대편 테이블의 외래 키를 관리하는 특이한 구조
    • FK 위치와 연관관계 주인 위치가 달라서 @JoinColumn을 꼭 사용해야 함. 안쓰면 조인 테이블 생김
    • FK 위치와 연관관계 주인 위치가 달라서 일쪽에서 저장 시 FK 매핑을 위한 쿼리가 추가적으로 나감 권장 X
    • 다쪽에서 일쪽을 접근할 일이 없어도 다대일로 설계하는게 장점이 많다. 다대일로 설계하자.
  • /일대다 양방향
    • 다쪽에서 값 수정 시 FK가 업데이트 되지 않도록 억지로 읽기 전용으로 설계해야 나오는 구조.
    • 공식적으로 없는 구조.
    • 다대일로 설계하자.

/일대일 [1:1]

  • 주 테이블, 대상 테이블 중에 외래 키를 선택해서 둬야 하고, 외래 키에 DB 유니크 제약조건을 추가하자.
  • 일대일 관계에서는 기본적으로 내 엔티티에 있는 외래키는 내가 관리한다.
  • /일대일: 주 테이블에 외래 키 단방향
    • 다대일(@ManyToOne) 단방향 매핑과 유사
  • /일대일: 주 테이블에 외래 키 양방향
    • 다대일 양방향 매핑 처럼 외래 키가 있는 곳이 연관관계의 주인.
    • 반대편은 mappedBy
  • /일대일: 대상 테이블에 외래 키 단방향
    • 주 테이블이 아닌 대상 테이블에 FK를 두고 단방향 매핑하는 건 지원도 안되고 불가능함.
  • /일대일: 대상 테이블에 외래 키 양방향
    • 말에 어폐가 있는데, 사실 대상 테이블을 연관관계 주인으로 잡고 매핑을 한다.
    • 일대일 주 테이블에 외래 키 양방향과 매핑 방법이 같다.
    • FK 위치만 바뀐 것.
  • 일대일에서 /트레이드 오프: 주 테이블과 대상 테이블 중 어디에 FK를 둘 것인가?
    • 주 테이블이 연관관계 주인
      • 개발자 입장: 서버 성능에 유리함(대상 테이블 데이터 유무). JPA 매핑 편리. FK에 null 허용해야 하는 단점.
      • DBA 입장: FK를 옮겨야 하고, 코드 수정해야하고,… 싫어한다.
    • 대상 테이블이 연관관계 주인
      • DBA 입장: 주 테이블: 대상 테이블 = 1:다가 되면, 대상 테이블에 FK가 있어 대상 테이블이 주인이 되는게 유리함. (테이블 구조 변경 거의 없음)
      • 개발자 입장: 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨
        • 테이블에는 Member에 Locker 칼럼이 없기 때문에, Member 객체의 Locker 필드에 null을 넣을지 말지 결정하기 위해서는 Locker 테이블을 뒤져야 함. 어쩔 수 없이 항상 즉시 로딩 되버림.
  • /일대일 정리
    • 주 테이블에 외래 키
      • 주 객체가 대상 객체의 참조를 가지는 것 처럼
        주 테이블에 외래 키를 두고 대상 테이블을 찾음
      • 객체지향 개발자 선호
      • JPA 매핑 편리
      • 장점: 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인 가능
      • 단점: 값이 없으면 외래 키에 null 허용
    • 대상 테이블에 외래 키
      • 대상 테이블에 외래 키가 존재
      • 전통적인 데이터베이스 개발자 선호
      • 장점: 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테이블 구조 유지
      • 단점: 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨 (프록시는 뒤에서 설명)
        • 프록시 객체를 만들 때, Member에 Locker 필드가 존재하기 때문에(양방향), 결국에 Locker 필드를 뒤져야 한다.
        • (Locker 필드를 뒤져야 null을 넣을지 말지를 알 수 있기 때문이다)

/다대다 [N:M]: 쓰지 말자.

  • JPA가 중간 테이블을 만들어낸다.
  • 객체에서 /다대다
    • 객체는 컬렉션을 사용해서 객체 2 개로 다대다 관계 가능
  • /다대다 매핑의 한계
    • 편리해 보이지만 실무에서 사용X
    • 연결 테이블이 단순히 연결만 하고 끝나지 않음
  • /다대다 한계 극복: 연결 테이블용 엔티티를 추가해 연결테이블을 엔티티로 승격시키자.
  • 실전에서는 @ManyToMany 사용X

애노테이션 속성

  • /@JoinColumn
속성 설명 기본값
name 매핑할 외래 키 이름 필드명 + _ + 참조하는 테이블의 기본 키 컬럼명
referencedColumnName 외래 키가 참조하는 대상 테이블의 컬럼명 참조하는 테이블의 기본 키 컬럼명
foreignKey(DDL) 외래 키 제약조건을 직접 지정할 수 있다. 이 속성은 테이블을 생성할 때만 사용한다.
unique, nullable, insertable, updatable, columnDefinition, table @Column의 속성과 같다.
  • /@ManyToOne - 주요 속성
속성 설명 기본값
optional false로 설정하면 연관된 엔티티가 항상 있어야 한다. TRUE
fetch 글로벌 페치 전략을 설정한다. - @ManyToOne=FetchType.EAGER
- @OneToMany=FetchType.LAZY
cascade 영속성 전이 기능을 사용한다.
targetEntity 연관된 엔티티의 타입 정보를 설정한다. 이 기능은 거의 사용하지 않는다. 컬렉션을 사용해도 제네릭스로 타입 정보를 알 수 있다. 몰라도 된다
  • /@OneToMany - 주요 속성
속성 설명 기본값
mappedBy 연관관계의 주인 필드를 선택한다.
fetch 글로벌 페치 전략을 설정한다. - @ManyToOne=FetchType.EAGER
- @OneToMany=FetchType.LAZY
cascade 영속성 전이 기능을 사용한다.
targetEntity 연관된 엔티티의 타입 정보를 설정한다. 이 기능은 거의 사용하지 않는다. 컬렉션을 사용해도 제네릭스로 타입 정보를 알 수 있다.

Ref) 김영한 자바 ORM 표준 JPA 프로그래밍 - 기본편

'DB Access > JPA' 카테고리의 다른 글

[JPA] 프록시와 연관관계 관리  (0) 2025.07.01
[JPA] 고급 매핑 - 상속 관계 매핑  (0) 2025.07.01
[JPA] 연관관계 매핑 기초  (0) 2025.07.01
[JPA] 엔티티 매핑  (0) 2024.11.08
[JPA] 영속성 관리  (0) 2024.11.06
'DB Access/JPA' 카테고리의 다른 글
  • [JPA] 프록시와 연관관계 관리
  • [JPA] 고급 매핑 - 상속 관계 매핑
  • [JPA] 연관관계 매핑 기초
  • [JPA] 엔티티 매핑
lumana
lumana
배움을 나누는 공간 https://github.com/bebeis
  • lumana
    Brute force Study
    lumana
  • 전체
    오늘
    어제
    • 분류 전체보기 (462)
      • 개발 일지 (0)
        • Performance (0)
        • TroubleShooting (0)
        • Refactoring (0)
        • Code Style, Convetion (0)
        • Architecture (0)
      • Software Engineering (36)
        • Test (8)
        • 이론 (18)
        • Clean Code (10)
      • Java (72)
        • Basic (5)
        • Core (21)
        • Collection (7)
        • 멀티스레드&동시성 (13)
        • IO, Network (8)
        • Reflection, Annotation (3)
        • Modern Java(8~) (13)
        • JVM (2)
      • Spring (53)
        • Framework (12)
        • MVC (23)
        • Transaction (3)
        • AOP (11)
        • Boot (0)
        • AI (0)
      • DB Access (16)
        • Jdbc (1)
        • JdbcTemplate (0)
        • JPA (14)
        • Spring Data JPA (0)
        • QueryDSL (0)
      • Computer Science (130)
        • Data Structure (27)
        • OS (14)
        • Database (10)
        • Network (21)
        • 컴퓨터구조 (6)
        • 시스템 프로그래밍 (23)
        • Algorithm (29)
      • HTTP (8)
      • Infra (1)
        • Docker (1)
      • 프로그래밍언어론 (15)
      • Programming Language(Sub) (76)
        • Kotlin (0)
        • Python (25)
        • C++ (51)
        • JavaScript (0)
      • FE (11)
        • HTML (1)
        • CSS (9)
        • React (0)
        • Application (1)
      • Unix_Linux (0)
        • Common (0)
      • PS (13)
        • BOJ (7)
        • Tip (3)
        • 프로그래머스 (0)
        • CodeForce (0)
      • Book Review (4)
      • Math (3)
        • Linear Algebra (3)
      • AI (7)
        • DL (0)
        • ML (0)
        • DA (0)
        • Concepts (7)
      • 프리코스 (4)
      • Project Review (6)
      • LegacyPosts (11)
      • 모니터 (0)
      • Diary (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
lumana
[JPA] 다양한 연관관계 매핑
상단으로

티스토리툴바