[JPA] 연관관계 매핑 - 1:1

Bam·2025년 5월 19일

Spring

목록 보기
58/77
post-thumbnail

일대일 OneToOne

일대일 관계는 엔티티 하나가 다른 엔티티 한 개와 관계를 가지는 연관관계입니다. 예를들어 학생증을 받으면 학생증은 하나의 학생에서 대해서만 유효하고 반대로 학생도 본인에게 유효한 학생증 하나만을 사용할 수 있습니다.

이처럼 일대일 관계에서 그 반대 연관관계도 항상 일대일 연관관계가 유지됩니다.

지난 포스트에서 다대일을 다루면서 다대일 연관관계의 주인은 항상 다 쪽이 가져간다고 했었는데요. 일대일 연관관계에서는 어느 쪽이든 외래 키를 가진 주인이 될 수 있습니다.


주인 테이블에 외래 키를 주는 경우

위 테이블 구조에서 학생 테이블이 주인 테이블 되고 학생증 테이블이 대상 테이블이 됩니다. 그리고 외래 키를 주인 테이블인 학생 테이블에 넘겨주었습니다.

이 방식은 주인 테이블을 통해 대상 테이블을 참조할 수 있어서 객체지향 프로그래밍과 같은 느낌으로 사용할 수 있습니다.

단방향

@Entity
@Table(name = "students_table")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "s_id", nullable = false)
    private Long id;

    @OneToOne(fetch = FetchType.LAZY)   // 단방향 1:1
    @JoinColumn(name = "sic_id", nullable = false, unique = true)
    private StudentIdCard studentIdCard;

    // 생성자 및 getter
}
@Entity
@Table(name = "student_id_cards_table")
public class StudentIdCard {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "sic_id", nullable = false)
    private Long id;

    // 생성자 및 getter
}

단방향이므로 주인 엔티티 쪽에만 연관관계 매핑 정보(@OneToOne)을 사용합니다.

양방향

@Entity
@Table(name = "students_table")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "s_id", nullable = false)
    private Long id;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "sic_id", nullable = false, unique = true)
    private StudentIdCard studentIdCard;
    
    //생성자 및 getter
}
@Entity
@Table(name = "student_id_cards_table")
public class StudentIdCard {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "sic_id", nullable = false)
    private Long id;

    @OneToOne(mappedBy = "studentIdCard", fetch = FetchType.LAZY)
    private Student student;
    
    //생성자 및 getter
}

외래 키를 가진 학생 테이블이 주인 테이블(엔티티)이므로 대상 엔티티인 학생증 엔티티에 mappedBy 속성을 반드시 명시해줍니다.

대상 테이블에 외래 키를 주는 경우

이번엔 반대로 대상 테이블에 외래 키를 넘겨준 상황입니다.

이 방식은 테이블 관계가 일대다로 변경되는 상황에서 테이블 구조를 유지할 수 있다는 장점이 있습니다.

단방향

JPA는 대상 테이블이 외래 키를 가진 단방향 일대일 연관관계 매핑은 지원하지 않습니다.

그래서 이 경우에 단방향 일대일 연관관계를 매핑하고 싶다면 학생증 테이블(엔티티)를 주인처럼 취급하도록 하거나(위 단방향 예시에서 @OneToOne 매핑을 학생 대신 학생증 엔티티에 사용) 양방향 연관관계를 사용해야합니다.

양방향

@Entity
@Table(name = "students_table")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "s_id", nullable = false)
    private Long id;

	@OneToOne(mappedBy = "student", fetch = FetchType.LAZY)
    private StudentIdCard studentIdCard;
    
    //생성자 및 getter
}
@Entity
@Table(name = "student_id_cards_table")
public class StudentIdCard {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "sic_id", nullable = false)
    private Long id;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "s_id", nullable = false, unique = true)
    private Student student;
    
    //생성자 및 getter
}

기존 양방향의 매핑만 바꿔서 사용하시면 됩니다.

0개의 댓글