JPA 연관관계 매핑의 종류
JPA 연관관계 매핑의 종류는 @ManyToOne, @OneToMany, @OneToOne, @ManyToMany가 있다.
이 글에서는 @OneToOne 관계에 대해 다룬다.
아래 예제에서는 Member(멤버)가 하나씩 가질 수 있는 Locker(사물함)을 가정했다.
@OneToOne(일대일 매핑)
기본적으로 @ManyToOne의 매핑 관계와 유사하다.
Member와 Locker(사물함) 엔티티가 1대 1 매핑된다고 가정하자.
일대일 매핑시에는 FK에 unique 제약조건을 추가하는 것이 좋다.
일대일 단방향 (ex 1)
(Member가 연관관계의 주인)
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String username;
@OneToOne
@JoinColumn(name = "LOCKER_ID", unique = true)
private Locker locker;
}
@Entity
public class Locker {
@Id @GeneratedValue
private Long id;
private String name;
}
Member가 연관관계의 주인이 되고, Locker에 대한 FK를 가지게 된다.
ManyToOne 단방향 매핑과 매우 유사하다.
일대일 단방향 (ex 2)
(Locker가 연관관계의 주인)
반대로 Locker가 연관관계의 주인이 되고 Member에 대한 FK를 가질 수도 있다.
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String username;
}
@Entity
public class Locker {
@Id @GeneratedValue
private Long id;
private String name;
@OneToOne
@JoinColumn(name = "MEMBER_ID", unique = true)
private Member member;
}
OneToOne 양방향 매핑 (ex 3)
(Member가 연관관계의 주인)
이것도 마찬가지로 ManyToOne 양방향 매핑과 유사하게 mappedBy 속성을 이용하면 된다.
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String username;
@OneToOne
@JoinColumn(name = "LOCKER_ID")
private Locker locker;
}
@Entity
public class Locker {
@Id @GeneratedValue
private Long id;
private String name;
@OneToOne(mappedBy = "locker")
private Member member;
}
Member가 연관관계의 주인이고, Locker에서도 mappedBy를 통해 Member와 매핑하여 Member 필드를 사용할 수 있다.
이 또한 ManyToOne 양방향 매핑과 유사하다.
단방향 연관관계 - 대상 테이블에 외래키 설정은 불가하다.
JPA에서는 단방향 연관관계 설정 시 아래 그림과 같이 대상 테이블에 외래키를 두는 방법은 불가하다.
Member 객체에 Locker 필드가 존재하지만, 테이블에는 LOCKER 쪽에서 MEMBER_ID(FK)를 설정할 수는 없다.
Member테이블에 Locker필드가 있고, Member가 연관관계의 주인이라면 Member 쪽에 LOCKER_ID (FK)를 두어야 한다.
만약 위와 같은 그림에서처럼 Locker쪽에 MEMBER_ID(FK)를 두고 싶다면,
Locker를 연관관계의 주인으로 하여 (ex3)의 반대 상황으로 Locker 쪽에 MEMBER_ID(FK)를 만들면 된다.
즉, 연관관계의 주인인 쪽에서 데이터를 CRUD 하고, 대상 테이블 쪽에서는 읽기만 가능하게 된다.
일대일 매핑 시 외래 키 위치에 따른 trade off 관계
Member와 Locker의 관계에서 Member가 주 테이블일 것이고, Locker가 대상 테이블일 것이다.
주 테이블에 외래키 위치 시
- 주 객체가 대상 객체의 참조를 가지는 것처럼 주 테이블에 외래키를 두고 대상 테이블을 찾음
- 객체지향 개발자가 선호하는 방법이다.
- JPA 매핑이 편리하다.
- 장점 : 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인할 수 있다.
- 단점 : 대상 테이블(Locker)이 비어있으면 외래 키에 null이 들어간다.
대상 테이블에 외래키 위치 시
- 대상 테이블에 외래키를 위치시킨다.
- 데이터베이스 개발자가 선호하는 방법이다.
- 장점 : 주 테이블과 대상 테이블을 일대일 관계에서 이후 일대다 관계로 변경할 때 용이하다.
- 단점 : 프락시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩되게 된다.
(참고) 인프런 - 김영한 님 '자바 ORM 표준 JPA 프로그래밍 - 기본 편'
https://www.inflearn.com/course/ORM-JPA-Basic
'Database > JPA' 카테고리의 다른 글
[JPA] 연관 관계 매핑 - @ManyToMany (0) | 2023.10.06 |
---|---|
[JPA] 연관관계 매핑 (1) | 2023.10.06 |
[JPA] 연관관계 매핑 - @ManyToOne, @OneToMany (0) | 2023.10.06 |
[JPA] @Entity - 필드와 컬럼 매핑의 여러가지 속성 (1) | 2023.10.04 |
[JPA] @Entity - 기본 키 매핑 (1) | 2023.10.04 |