Post

[JPA #2] 연관관계 매핑

[JPA #2] 연관관계 매핑

주요 키워드

  • 엔티티 매핑
  • 일대일(1:1) 관계
  • 일대다(1:N) 관계
  • 다대일(N:1) 관계
  • 다대다(N:M) 관계

엔티티 매핑 기본

@Entity 사용 시 유의사항

  • JPA로 테이블과 매핑할 클래스는 반드시 @Entity 선언 필요
  • 기본 생성자 필수 (public 또는 protected)
  • final, enum, interface, inner class 사용 불가
  • 필드에 final 사용 금지
  • 테이블 이름과 다른 경우 @Table(name = "table_name")으로 설정

애플리케이션 실행 시 DDL 자동 생성 설정 (개발 환경 전용)

옵션설명
create기존 테이블 drop 후 create
create-dropcreate 후 종료 시 drop
update변경분만 반영 (운영 X)
validate매핑 검증
none사용 안 함

운영환경에는 절대 create, create-drop, update 사용 금지
validate, none만 사용

DDL 생성 관련 어노테이션

1
@Column(unique = true, length = 10)
  • 실행 로직에는 영향 X, 테이블 생성 시에만 적용

필드와 컬럼 매핑

  • Enum 타입 매핑 시 ORDINAL 사용 금지, STRING 사용 권장
    • 이유: ORDINAL 사용시 enum 순서가 변경되면 데이터 불일치 발생

객체 연관관계 vs 테이블 연관관계

  • 객체는 참조, 테이블은 외래 키로 연관관계 표현
  • 객체의 양방향 연관관계 = 단방향 연관관계 2개
  • 테이블은 외래 키 하나로 양쪽 조인 가능

연관관계의 주인

  • 외래 키가 있는 쪽이 주인
  • 주인만이 외래 키를 등록/수정할 수 있음
  • 주인은 mappedBy 사용하지 않음
  • 연관관계 편의 메서드를 한쪽에만 구현하는 것이 좋음
  • toString, lombok, JSON 직렬화 시 순환 참조 주의
  • 컨트롤러에서 엔티티 직접 반환 금지 → DTO로 변환

연관관계 매핑 어노테이션

1. 다대일 (N:1)

  • @ManyToOne
  • 실무에서 가장 많이 사용

2. 일대다 (1:N)

  • @OneToMany
  • 일대다 단방향은 거의 사용하지 않음
  • 양방향 시 @JoinColumn(insertable = false, updatable = false)로 읽기 전용 지정
  • 다대일 단방향 매핑 권장

3. 일대일 (1:1)

  • @OneToOne
  • 양쪽 어느 테이블에 외래 키가 있어도 무관
  • 외래 키에 unique 제약 추가
  • 단방향에서 대상 테이블에 외래 키가 있는 경우는 JPA가 지원하지 않음

4. 다대다 (N:M)

  • @ManyToMany (사용 지양)
  • 연결 테이블을 엔티티로 승격하여 다대일/일대다로 풀어서 매핑

상속 관계 매핑

RDB는 상속 개념이 없음 → 논리적 모델링 필요
JPA에서는 세 가지 전략으로 매핑 가능

1. 조인 전략 (@Inheritance(strategy = JOINED))

  • 자식 테이블에 외래 키 → 부모와 조인
  • 정규화 잘됨, 저장 공간 효율
  • 조회 시 조인이 많고 쿼리가 복잡

2. 단일 테이블 전략 (@Inheritance(strategy = SINGLE_TABLE))

  • 하나의 테이블에 모두 저장, DType 컬럼 구분
  • 조회 빠름, 쿼리 단순
  • NULL 허용 컬럼 증가 → 성능 저하 가능

3. 구현 클래스마다 테이블 전략 (@Inheritance(strategy = TABLE_PER_CLASS))

  • 각 클래스마다 테이블 생성
  • not null 제약 가능
  • 조인 불가, 통합 쿼리 어려움

@DiscriminatorColumn, @DiscriminatorValue로 DType 설정 권장


공통 매핑 정보 - @MappedSuperclass

  • 공통 필드(예: 생성일, 수정일 등)를 별도 상위 클래스에 선언
  • @MappedSuperclass 선언
  • 상속받은 하위 클래스에서 매핑 정보만 전달받음 (자체는 엔티티 아님)
  • 조회 불가, 직접 사용 불가 → 추상 클래스로 선언 권장
This post is licensed under CC BY 4.0 by the author.