• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

스프링 데이터 jpa 페이징 (countQuery) 질문입니다

23.04.17 23:16 작성 조회수 812

0

안녕하세요. 강의 영상보고 data jpa 를 사용해 프로젝트 진행중에 있습니다.

다름이 아니라 카운트 쿼리에

countQuery = "SELECT count(a) from Article a inner join fetch a.content where a.category =:categoryId and (a.title like %:keyword% or a.content.content like %:keyword%) 

join fetch 하면 에러가 발생하였고, 해다 에러 발생 이유는 구글링 후에 확인할 수 있었습니다.

이유: 그런데 여기서 문제는 fetch join은 객체 그래프를 조회하는 기능이기 때문에 연관된 부모가 꼭 있어야 합니다. 그런데 수를 뽑는 count(u)로 조회 결과가 변경되어버렸기 때문에, 오류가 발생한 것이지요.

그런데 하나 의문점이 생깁니다.
해당 쿼리 내용을 보면, join 한 엔티티의 요소를 where절에서 찾고 있습니다.( a.content.content like %:keyword%)

그런데 제가 알고 있는 개념으로는, 기본 Lazy loading 을 사용하게 되면, 연관되어 있는 엔티티를 프록시로 가져오는 것으로 알고 있습니다.

그렇게 되면 저 where절의 부분에서 content가 프록시로 들어갔기 때문에, 올바르게 동작하면 안된다고 생각합니다.

fetch를 사용하지 않아도, inner join으로만 쿼리가 날라가도, 쿼리 자체는 전부 실행되는 것인가요?

그런데 가만히 생각해보면 그런 방식이라면, 지연로딩을 사용하는 방식이 사용자가 필요로 하지 않는 정보까지 join 하는 데이터베이스의 부하를 줄이기 위해 이렇게 하는 것으로 알고 있는데, fetch를 사용하지 않아도 데이터베이스에는 완전한 쿼리가 날라간다면, 이걸 굳이 스프링이 proxy로 끼워줄 필요가 있나? 하는 생각도 듭니다.

따라서 요약해보면,
카운트 쿼리에서 조건에 따라 count 가 달라지므로, join을 할 때 fetch 를 넣지 않아도, 올바르게 작동하는 것이 맞는지
맞다면 fetch를 사용하지 않아도 실제 데이터베이스에는 join 연산이 항상 일어나는 것이고, 대신 엔티티에 반환 해 줄 때, 프록시로 들어가는 것이고
fetch 를 사용하게 되면 나왔던 모든 결과가 엔티티로 들어가 는 것이 맞는지 입니다.
jpa 책이랑 웹 전부 뒤져봤는데 이 부분이 약간 모호해서 질문드립니다!

답변 2

·

답변을 작성해보세요.

0

lee님의 프로필

lee

질문자

2023.04.20

jpa에서 일어나는 현상과 데이터베이스에 일어나는 현상에 대해서 명확하게 구별했어야 됐는데, 모호하게 사용하다 보니 이런 고민이 생겼던 것 같습니다. 답변 주신 부분으로 인해서 너무 명확해졌습니다 감사합니다!!

0

안녕하세요. lee님

join은 SQL에서 여러 테이블의 데이터를 조인해서 조회할 때 사용합니다.

fetch join은 JPA에서 제공하는 특수한 기능입니다. 이 기능은 DB에서 제공하는 SQL 기능과는 무관합니다. 이 기능은 엔티티를 조회할 때 연관된 엔티티를 한번에 함께 조회하는 기능입니다. 참고로 JPA에서 fetch join을 사용하더라도 SQL에서는 여러 테이블을 함께 조회해야 하기 때문에 결국 join문으로 변경이 됩니다. 연관된 엔티티를 함께 조회한다는 뜻은 SQL 입장에서 보면 결국 JOIN을 사용하는 것이지요.

결과적으로 카운트 숫자를 조회하는 기능은 엔티티를 조회하는 기능이 아니기 때문에 fetch join을 사용하면 안됩니다. 이 경우에는 일반 join을 사용해야 합니다.

마찬가지로 데이터를 DTO로 조회하는 경우에도 fetch join을 사용할 수 없습니다. 이때도 일반 join을 사용해야 합니다.

감사합니다.