hyelie
hyelie
Hyeil Jeong
       
글쓰기    관리    수식입력
  • 전체보기 (495)
    • PS (283)
      • Algorithm (28)
      • PS Log (244)
      • Contest (6)
      • Tips (5)
    • Development (52)
      • Java (14)
      • Spring (23)
      • SQL (2)
      • Node.js (2)
      • Socket.io (3)
      • Study (4)
      • Utils (4)
    • DevOps (36)
      • Git (5)
      • Docker (4)
      • Kubernetes (2)
      • GCP (3)
      • Environment Set Up (8)
      • Tutorial (12)
      • Figma (2)
    • CS (74)
      • OOP (7)
      • OS (24)
      • DB (2)
      • Network (24)
      • Architecture (0)
      • Security (2)
      • Software Design (0)
      • Parallel Computing (15)
    • Project (15)
      • Project N2T (5)
      • Project ASG (0)
      • Project Meerkat (1)
      • Model Checking (7)
      • Ideas (2)
    • 내가 하고싶은 것! (34)
      • Plan (16)
      • Software Maestro (10)
      • 취준 (8)
hELLO · Designed By 정상우.
hyelie

hyelie

Development/Spring

[JPA] JPA Join 이슈, FETCH JOIN의 사용

Join 방향 이슈

A : B = 1 : N의 관계일 때 일반적으로 B에서 ManyToOne을 가지고 있다. 이 경우 B Join FETCH A는 되지만 A Join FETCH B를 하면 작동하지 않는다. 왜냐하면 B에서 A 정보는 있지만 A에서 B 정보는 없기 때문이다. 이를 해결하기 위해서는

 

- 양방향 관계를 넣던가,

- B.getA()로 A 정보를 가져오던가,

- SQL JOIN하듯

SELECT b FROM A a JOIN B b ON b.A = a;

이렇게 하면 된다. 그냥 INNER JOIN하는 것 처럼 된다. 다만 이러면 join을 해버리는 것이기 때문에 성능상 이슈를 생각해야 한다.

 

 

 

Fetch Join의 사용 이유

그리고 또 하나. FETCH JOIN을 사용하는 이유를 깨달은 것 같은데.

 

처음에는 B에 있는 정보를 찾기 위해서

SELECT b FROM B b WHERE B.a = ?;

이런 식으로 B에 있는 A의 값이 얼마인 것에 대해 검색했다. 그런데 오늘 짜다가 B.a가 NULL인 것을 발견했다. 아 이렇게 하면 안되는구나. 이유는, JPA 영속성에 DB의 모든 값이 있는 게 아니라 필요한 걸 필요할 때 불러오는 형식인 FetchType.LAZY를 사용했는데 (N+1 문제를 막기 위해) DB에만 값이 있고, 영속성에는 값이 없을 경우 JPA가 B 내에 있는 a를 불러올 생각을 안한다. FetchType을 LAZY를 사용했기 때문에 이게 맞는 동작 방식이고, 따라서 null값이 된다. 

 

이걸 해결하기 위해 FetchType.EAGER로 바꿔버리면 B.a를 조회할 때마다 매번 query가 날아간다. N+1 문제인 것이다. 그래서 조회를 할 때 FETCH JOIN을 해서 B와 연관되어 있는 모든 A를 불러와서 N+1 문제를 막음과 동시에 필요할 때 fetch join을 사용해서 필요한 값을 한 번에 가져오는 것이다.

 

SELECT b FROM B b JOIN FETCH b.a WHERE b.a = ?;

이런식으로 짜면 양방향 구성을 하지 않고 join 1번으로 b.a에 해당하는 모든 b, a를 영속성으로 불러올 수 있게 되는 것 같다.

 

처음에는 "아니 JOIN 할 이유가 없는데 왜 JOIN하는 거지"라고 생각했었는데, 너무 DB에 초점이 맞춰진 생각이었다는 것을 느꼈고, Fetch Join과 join의 차이를 너무 몰랐구나 싶다. DB에는 있는 값이니까 당연히 검사할 수 있을 줄 알았는데 아니었다. 영속성에 데이터가 있는지 없는지 모르기 때문에 JOIN FETCH를 하는 것을 알게 되었다. 이제 조금 감이 많이 온다.

 

 

 

'Development > Spring' 카테고리의 다른 글

[Spring + Jwt] Spring Boot + Spring Security + Redis + Jwt를 이용한 회원가입 및 로그인  (0) 2022.10.05
[Spring + Redis] Spring Redis 연동  (0) 2022.10.04
[JPA] JPQL FROM절 subquery를 해결하는 방법 (inline view)  (0) 2022.10.04
[Spring] DTO와 Entity 간의 변환  (0) 2022.10.04
[JPA] JPA @IdClass에 관해,,,  (0) 2022.10.04
    hyelie
    hyelie

    티스토리툴바