본문 바로가기
JPA & Hibernate

JPA 연관관계 매핑 기초

by Salt-Fn 2023. 2. 23.

인프런의 자바 ORA 표준 JPA 프로그래밍 - 기본편과 자바 ORM 표준 JPA 책을 공부하며 정리한 포스트입니다.

 

단반향 연관관계

다대일(N:1)

(위) 객체 연관관계, (아래) 테이블 연관관계

객체 연관관계

  • 회원 객체는 Member.team 필드로 팀 객체와 연관관계를 맺는다.
    • 회원 객체와 팀 객체는 단방향 관계다.
    • 회원은 Member.team 필드를 통해서 팀을 알 수 있지만 반대로 팀은 회원을 알 수 없다.

테이블 연관관계

  • 회원 테이블은 TEAM_ID 외래 키로 팀 테이블과 연관관계를 맺는다.
  • 회원 테이블과 팀 테이블은 양방향 관계다. TEAM_ID 외래 키를 통해서 회원과 팀을 조인할 수 있고 반대로 팀과 회원도 조인할 수 있다.

객체 연관관계와 테이블 연관관계의 차이점

참조를 통한 연관관계는 언제나 단방향이다. 객체간에 연관관계를 양방향으로 만들고 싶으면 반대쪽에도 필드를 추가해서 참조를 보관해야 한다. 하지만 이것은 양방향 관계가 아닌 서로 다른 단방향 관계 2개다. 반면에 테이블은 외래 키 하나로 양방향으로 조인할 수 있다.

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

  • 객체는 참조로 연관관계를 맺는다.
  • 테이블은 외래 키로 연관관계를 맺는다.

객체 관계 매핑

이번엔 JPA를 사용해서 매핑을 했다.

Member Entity
Team Entity

  • @ManyToOne: 다대일 관계라는 매핑 정보다. 연관관계를 매핑할 때 다중성을 나타내는 어노테이션을 필수로 사용해야 한다.
  • @JoinColumn (name="TEAM_ID"): 조인 컬럼은 외래 키를 매핑할 때 사용한다. name 속성에는 매핑할 외래 키 이름을 지정한다. 이 어노테이션은 생략할 수 있다.

@JoinColumn

속성 기능 기본값
name 매핑할 외래 키 이름 필드명 + _ + 참조하는 테이블의 키본키 컬럼명
referencedColumnName 외래 키가 참조하는 대상 테이블의 컬럼명 참조하는 테이블의 기본키 컬럼명
foreignKey(DDL) 외래 키 제약조건을 직접 지정할 수 있다.
이 속성은 테이블을 생성할 때만 사용한다.
 
unique
nullable
insertable
updateable
columnDefinition
table
@Column  

@ManyToOne

속성 기능 기본값
optional false로 설정하면 연관된 엔티티가 항상 있어야 한다. true
fetch 글로벌 페치 전략을 설정한다. @ManyToOne=FetchType.EAGER
@OneToMany=FetchType.LAZY
cascade 영속성 전이 기능을 사용한다.  
targetEntity 연관된 엔티티의 타입 정보를 설정한다. 이 기능은 거의 사용하지 않는다. 컬렉션을 사용해도 제네릭으로 타입 정보를 알 수 있다.  

양방향 연관관계

위 객체 연관관계를 일대다 관계로 생각하면 Team 객체에 멤머를 가질 수 있게 List를 추가해야 한다.

데이터베이스 테이블은 외래 키 하나로 양방향으로 조회할 수 있으므로 데이터베이스에 추가 할 내용은 전혀 없다.

 

연관관계 주인

객체에는 양방향 연관관계라는 것이 없다.

 

객체

  • 회원 -> 팀 연관관계 1개 (단방향)
  • 팀 -> 회원 연관관계 1개 (단방향)

테이블

  • 회원 <->팀의 연관관계 1개 (양방향)

테이블은 외래 키 하나로 두 테이블의 연관관계를 관리 한다.

엔티티를 양뱡향 연관관계로 설정하면 객체의 참조는 둘인데 외래 키는 하나다. 이런 차이로 인해 JPA에서는 두 객체 연관관계 중 하나를 정해서 테이블의 외래키를 관리해야 하는데 이것을 연관관계의 주인이라 한다.

양방향 매핑의 규칙: 연관관계의 주인

양방향 연관관계 매핑 시 두 연관관계 중 하나를 연관관계의 주인으로 정해야 한다. 연관관계 주인만이 데이터베이스 연관관계와 매핑되고 외래키를 관리(등록, 수정, 삭제) 할 수 있다. 주인이 아닌 쪽은 읽기만 가능하다.

어떤 연관관계를 주인으로 정할지는 mappedBy 속성을 사용하면 된다.

  • 주인은 mappedBy 속성을 사용하지 않는다.
  • 주인이 아니면 mappedBy 속성을 사용해서 속성의 값으로 연관관계의 주인을 지정해야 한다.

연관관계 주인은 테이블에 외래 키가 있는 곳으로 정해야 한다.

*데이터베이스 테이블의 다대일, 일대다 관계에서는 항상 다 쪽이 외래 키를 가진다. 다 쪽인 @ManyToOne은 항상 연관관계의 주인이 되므로 mappedBy를 설정할 수 없다. 

순수한 객체까지 고려한 양방향 연관관계

객체 관점에서 양쪽 방향에 모두 값을 입력해주는 것이 가장 안전하다.

'JPA & Hibernate' 카테고리의 다른 글

JPA 고급 매핑  (0) 2023.03.03
JPA 다양한 연관관계 매핑  (0) 2023.02.27
JPA 엔티티 매핑  (0) 2023.02.22
JPA 영속성 관리  (0) 2023.02.20
JPA 시작  (0) 2023.02.20