JPA 1:1(일대일) 관계
일대일 관계는 주 테이블혹은 대상 테이블 중에 외래 키를 넣을 테이블 선택이 가능하다.
일대일 관계에서는 반대도 일대일 관계가 된다. 다대일 관계에서는 다(N)에 해당하는 곳이 외래 키를 가지고 있지만(연관관계의 주인)
일대일 관계에서는 주 테이블이나 대상 테이블에 외래 키를 둘 수 있어서 선택 해야 한다.
일대일 관계에서는 외래 키를 주 테이블에 둘지, 대상 테이블에 둘지에 따라 약간의 차이가 있다.
1. 주 테이블에 외래 키가 있는 경우
주 테이블에 외래 키를 둘 경우, 주 테이블에 매핑되는 주 객체에도 객체 참조를 두는 구조를 만들게 된다.
일대일 단방향
주 테이블 Parent에 단방향 일대일 관계에 해당하는 Child 객체필드를 만든후, @OneToOne 어노테이션 선언해준다.
@JoinColumn을 통해 Child 객체의 어떤 값과 조인할 건지를 정해준다.
(@JoinColumn 선언을 하지 않아도 Default 값이 있으나 값이 지저분하고, 좀더 명시적으로 알아볼 수 있도록 선언)
아래와 같이 작성한 일대일 단방향을 통해 주 테이블인 parent를 통해 일대일 연관관계로 놓인 대상 테이블 child 접근이 가능하다.
// 주 테이블 엔티티
@Entity
@Table(name = "parent")
@Getter
public class ParentEntity {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
@OneToOne
@JoinColumn(name = "id")
private ChildEntity childEntity;
}
// 대상 테이블 엔티티
@Entity
@Table(name = "child")
@Getter
public class ChildEntity {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
}
일대일 양방향
주 테이블에 외래키를 두고, 주 테이블과 대상 테이블 양쪽에서 서로를 참조하기 위해서 일대일 양방향 관계를 맺어줘야한다.
주 테이블에 해당하는 주 객체에는 일대일 단방향과 같이 @OneToOne과 @JoinColumn으로 대상 테이블 연관관계를 맺어준다.
대상 테이블에는 주 테이블 객체필드 선언후 @OneToOne 어노테이션 선언과 mappedBy 옵션으로 주 테이블의 어떤 필드와 연관되어 있는지를 선언해준다.
// 주 테이블 엔티티
@Entity
@Table(name = "parent")
@Getter
public class ParentEntity {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
@OneToOne
@JoinColumn(name = "id")
private ChildEntity childEntity;
}
// 대상 테이블 엔티티
@Entity
@Table(name = "child")
@Getter
public class ChildEntity {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
@OneToOne(mappedBy = "childEntity")
private ParentEntity parentEntity;
}
2. 대상 테이블에 외래 키가 있는 경우
일대일 단방향
JPA에서 대상 테이블에 외래 키를 두고 주 테이블에서 대상 테이블을 향해 일대일 단방향을 맺는 형태는 지원 하지 않고 있다.
일대일 양방향
주 테이블이 아닌 대상 테이블에 외래 키를 두고 양방향을 맺고 싶을 경우,
대상 테이블에 주 테이블 객체필드를 만든후 @OneToOne, @JoinColumn을 선언하고, 주 테이블에는 대상 테이블 객체를 만든후 @OneToOne 어노테이션과 mappedBy 옵션을 주면 된다( 주 테이블에 외래키를 두고 양방향을 맺을때와 정확히 거꾸로)
// 주 테이블 엔티티
@Entity
@Table(name = "parent")
@Getter
public class ParentEntity {
@Id
private long id;
@OneToOne(mappedBy = "parentEntity")
private ChildEntity childEntity;
}
// 대상 테이블 엔티티
@Entity
@Table(name = "child")
@Getter
public class ChildEntity {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@OneToOne
@JoinColumn(name = "id")
private ParentEntity parentEntity;
}
'Spring' 카테고리의 다른 글
[Spring] 구글 OAuth2.0 이용 소셜 로그인 구현 (0) | 2023.08.10 |
---|---|
[JPA]연관관계 - 다대다(N:M) (0) | 2023.08.09 |
[JPA] 연관관계 조회 방식별(Fetch, Lazy) 성능 차이 테스트 (0) | 2023.07.25 |
[Spring] MapStruct 사용 주의 사항 (0) | 2023.07.25 |
[Spring] Redis Template과 Redis Repository 특징과 장단점 (0) | 2023.07.24 |