Spring/Spring JPA
[JPA] @OneToOne
개발자잡
2024. 11. 25. 09:14
@OneToOne은 JPA에서 두 엔티티 간의 1:1 관계를 매핑하기 위해 사용하는 어노테이션입니다. 이는 관계형 데이터베이스의 1:1 관계를 표현하며, 두 테이블의 데이터가 서로 정확히 하나씩 연결되는 경우에 사용됩니다.
주요 특징
- 1:1 관계 매핑:
- 각 엔티티 인스턴스는 다른 엔티티의 인스턴스와 정확히 하나씩 매핑됩니다.
- 예를 들어, User 엔티티와 Profile 엔티티가 있을 때, 각 사용자는 하나의 프로필만 가질 수 있으며, 각 프로필은 하나의 사용자에만 속합니다.
- 연결 방식:
- 외래 키(Foreign Key)를 통해 연결됩니다.
- 관계를 주도하는 "소유 측(owner side)"와 "비소유 측(non-owner side)"로 나뉩니다.
- 지연 로딩:
- 기본적으로 @OneToOne 관계는 FetchType.EAGER로 설정됩니다.
- 필요에 따라 @OneToOne(fetch = FetchType.LAZY)로 변경해 사용할 수 있습니다.
주요 속성
- mappedBy:
- 관계의 주도권을 설정합니다.
- 소유 측이 아닌 엔티티에서 외래 키를 매핑할 필드를 지정합니다.
- fetch:
- 관계를 가져올 때 데이터를 로드하는 방식을 설정합니다.
- FetchType.EAGER: 즉시 로딩 (기본값).
- FetchType.LAZY: 지연 로딩.
- 관계를 가져올 때 데이터를 로드하는 방식을 설정합니다.
- cascade:
- 연관된 엔티티의 상태를 전이할지 설정합니다.
- 예: CascadeType.ALL, CascadeType.PERSIST, CascadeType.REMOVE 등.
- optional:
- 연관된 엔티티가 필수인지 여부를 설정합니다.
- 기본값은 true로, 연관된 엔티티가 없어도 허용합니다.
예제 1. 외래 키를 사용한 1:1 매핑
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "profile_id", referencedColumnName = "id") // 외래 키 매핑
private Profile profile;
}
@Entity
public class Profile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String bio;
}
User 엔티티는 Profile 엔티티와 1:1 관계를 가지며, profile_id 외래 키를 통해 연결됩니다.
예제 2) 양방향 1:1 매핑
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private Profile profile;
}
@Entity
public class Profile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String bio;
@OneToOne
@JoinColumn(name = "user_id") // 외래 키 정의
private User user;
}
- User가 "비소유 측", Profile이 "소유 측"으로 정의됩니다.
- mappedBy는 Profile 엔티티의 필드 이름을 가리킵니다.
실제 SQL 예시
위의 User와 Profile 예제를 기준으로 생성되는 SQL 테이블 구조:
CREATE TABLE User (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
profile_id BIGINT,
FOREIGN KEY (profile_id) REFERENCES Profile(id)
);
CREATE TABLE Profile (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
bio VARCHAR(255)
);
주요 활용 예
- 회원과 프로필:
- 회원(User) 테이블이 프로필(Profile) 테이블과 1:1로 매핑될 때.
- 주문과 배송 정보:
- 주문(Order) 테이블이 배송 정보(ShippingInfo) 테이블과 1:1로 매핑될 때.
주의점
- 외래 키 관리:
- 외래 키를 어느 쪽에서 관리할지 명확히 정의해야 합니다.
- 성능:
- 기본 FetchType.EAGER는 데이터가 항상 즉시 로드되므로 성능에 영향을 줄 수 있습니다. 필요에 따라 FetchType.LAZY를 설정하세요.
정리
@OneToOne은 1:1 관계를 명확히 표현하며, 관계형 데이터베이스 설계와 객체 지향 설계의 일관성을 유지하는 데 유용합니다.