Spring

[Spring] JPA Fetch Join

lakelight 2022. 9. 5. 14:33
728x90
반응형

Join

Entity에 Join을 걸어도 실제 쿼리에서 Select 하는 Entity는 오직 JPQL에서 조회하는 주체가 되는 Entity만 조회하여 영속화 합니다. 조회의 주체가 되는 Entity만 Select해서 영속화하기 때문에 데이터는 필요하지 않지만 연관 Entity검색조건필요한 경우에 주로 사용됩니다.

Fetch Join

조회의 주체가 되는 Entity 이외에 Fetch  Join이 걸린 연관 Entity함께 Select 하여 모두 영속화합니다. Fetch Join이 걸린 Entity 모두 영속화하기 때문에 Fetch Type이 Lazy인 Entity를 참조하더라도 이미 영속성 컨텍스트에 들어있기 때문에 따로 쿼리가 실행되지 않아 N+1 문제를 해결할 수 있습니다.

 

Fetch Join Ex

select m from Member m join fetch m.team

위의 JQPL은 아래의 SQL로 번역됩니다.

SELECT M.*, T.* FROM MEMBER M
INNER JOIN TEAM T ON M.TEAM_ID=T.ID

Fetch Join은 위와 같이 Entity를 한번에 가져옵니다. 즉, 지연로딩을 하지 않고 즉시 로딩으로 Entity에 대한 정보를 한번에 조회해서 가져옵니다.

이미지 출처: https://minkukjo.github.io/framework/2021/01/04/Spring-Data-JPA-27/

 

Fetch Join 주의할 점

Fetch Join을 진행하게 되면 Row가 중복되는 일이 많습니다. 이 문제는 아래와 같이 distinct 키워드를 통해 해결할 수 있습니다.

select distinct t from Team t join fetch t.members;

 

결론

Spring 에서 객체를 조회할 때 Fetch Type을 Lazy로 설정하여 프록시로 객체를 만들고
그 객체에 접근을 할 때 Query를 통해 영속성 컨텍스트로 객체를 가져오게 됩니다.

만약 1개의 팀에 10명의 선수가 있다면 팀을 조회하는데 1번,
10명의 선수를 각각 조회하는 데 10번의 쿼리가 발생합니다.

이러한 문제를 N+1문제라고 합니다. 이러한 문제를 해결하기 위해 Fetch Join을 이용합니다.
Fetch Join을 활용하여 Team과 Member의 Entity를 한번에 조회하여 1번의 조회만으로

모든 데이터에 접근을 할 수 있습니다. 이번 포스팅을 통해 Fetch Join에 대해 알아보았습니다.
포스팅 봐주셔서 감사합니다.

 

[참고]

1. 일반 Join과 Fetch Join

2. Fetch Join 기본

 

728x90
반응형