본문 바로가기
Backend/JPA

[JPA] OneToOne 연관관계 (mappedby / fetchType)

by 비전공자 기록광 2022. 10. 14.
반응형

매일같이 사용해도 매일같이 헷갈리는 연관관계를 다시 정리해봤다.

 

 

OneToOne 연관관계는 오직 서로가 하나뿐인 1:1 관계를 말하고 이 둘은 FK로 연결되어 있다.

OneToOne 연관관계의 특징을 알아보기 위해 엔티티를 만들어줬다.

 

하나는 Student 엔티티이고

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
 
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Student {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String name;
 
    @OneToOne
    private Passport passport;
 
    public Student(String name) {
        this.name = name;
    }
 
 
    @Override
    public String toString() {
        return String.format("Student[%s]", name);
    }
}
cs

 

 

또 다른 하나는 Passport 엔티티이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
 
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Passport {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String number;
 
   @OneToOne
    private Student student;
 
    public Passport(String number) {
        this.number = number;
    }
 
    @Override
    public String toString() {
        return String.format("Passport[%s]", number);
    }
}
 
cs

 

실습을 위한 간단한 데이터도 미리 넣어준다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
insert into passport(id,number)
values(40001,'E123456');
insert into passport(id,number)
values(40002,'N123457');
insert into passport(id,number)
values(40003,'L123890');
 
insert into student(id,name, passport_id)
values(20001,'한소희'40001);
insert into student(id,name, passport_id)
values(20002,'아이유'40002);
insert into student(id,name, passport_id)
values(20003,'김태리'40003);
cs

 

 

연관관계 주인 설정

이대로 서버를 실행하면

엔티티 둘다 관계를 가지는 FK 가 생성되는 것을 볼 수 있다.

 

하지만 이렇게 되면 데이터가 중복되기 때문에 별로 좋아보이지 않는다.

이 중복을 제거하기 위해 연관관계의 주인을 정의해준다. 

 

 

mappedBy = "연관관계의 주인"

 

그리고 서버를 시작하면 연관관계의 주인인 passport의 id가 FK로 정의되어 생성된 걸 확인할 수 있다.

 

 

 

 

Fetch.Type

OneToOne 연관관계에서는 fetch join의 default가 Eager이다.

즉 한쪽의 데이터를 조회해도 다른 쪽의 데이터가 같이 가져와진다는 것이다.

 

간단히 findById를 통해 가져온 Student를 로그로 찍어보는 테스트를 진행했다.

 

 

🛑 둘다 정의 안함 (Default Eager)

 

둘다 정의 안한 디폴트 상황일때 OneToOne 연관관계는 fetch.Type을 Eager를 갖는다.

테스트를 실행해보면 left outer join을 통해 student와 passport를 조인해와 해당 학생의 passport 정보를 뿌려준다.

 

 

학생 id 20001 의 passport number은 E123456 이다.

잘 가져온 걸 볼 수 있다.

 

 

🛑 Passport 연관관계의 주인, FetchType.LAZY

 

위에 모두 Eager일때와 같다.

 

 

🛑 Student FetchType.LAZY

 

이렇게 되면 select 쿼리를 두번 날린다.

Student에서 Passport와의 관계를 LAZY로 정의했기때문에

Student에서 select할 때 join하지 않는다.

 

하지만 Passport에서는 default = Eager 상태이기 때문에

뒤이어 Passport에서 Student로 조인해 해당 student의 FK로 연결된 passport_id를 가져온다.

 

 

 

🛑 둘다 Lazy

 

 

이 경우에는 각각의 테이블로 두번 select 요청을 보내어

학생 id에 해당하는 학생의 passport id를 가져와 passport 정보를 가져온다.

 

 

각각 설정만 다르게 해줘도 요청의 결과가 달라진다.


코드

TIL/Spring_Boot/jpa_study/src/main/java/com/udemy/jpa_study/relationships at main · recordbuffer/TIL · GitHub

 

GitHub - recordbuffer/TIL: Today I Learned

Today I Learned. Contribute to recordbuffer/TIL development by creating an account on GitHub.

github.com

 

참고

https://www.udemy.com/share/101XoW3@elgoPx8G1T8cav5XKpLRW3l1YMiA0G9QVjj9LVY4DZHANcC8MBEdqpgFoppJBXcag==/

 

Master Hibernate and JPA with Spring Boot in 100 Steps

Learn Hibernate, JPA (Java Persistence API) and Spring Data JPA using Spring and Spring Boot

www.udemy.com

http://www.kyobobook.co.kr/product/detailViewKor.lafejkGb=KOR&mallGb=KOR&barcode=9788960777330&orderClick=LAG&Kc=

 

자바 ORM 표준 JPA 프로그래밍 | 김영한 - 교보문고

자바 ORM 표준 JPA 프로그래밍 | 자바 ORM 표준 JPA는 SQL 작성 없이 객체를 데이터베이스에 직접 저장할 수 있게 도와주고, 객체와 관계형 데이터베이스의 차이도 중간에서 해결해준다. 이 책은 JPA

product.kyobobook.co.kr

 

반응형

댓글