티스토리 뷰

JPA

[QueryDSL] fetchResults()가 deprecated 된 이유

토마토계란 2024. 2. 26. 22:37

 

AbstractJPAQuery.fetchResults(); 의 함수 주석을 가져와봤다.

fetchResults requires a count query to be computed. In querydsl-sql, this is done by wrapping the query in a subquery, like so: SELECT COUNT(*) FROM (<original query>). Unfortunately, JPQL - the query language of JPA - does not allow queries to project from subqueries. As a result there isn't a universal way to express count queries in JPQL. Historically QueryDSL attempts at producing a modified query to compute the number of results instead. However, this approach only works for simple queries. Specifically queries with multiple group by clauses and queries with a having clause turn out to be problematic. This is because COUNT(DISTINCT a, b, c), while valid SQL in most dialects, is not valid JPQL. Furthermore, a having clause may refer select elements or aggregate functions and therefore cannot be emulated by moving the predicate to the where clause instead. In order to support fetchResults for queries with multiple group by elements or a having clause, we generate the count in memory instead. This means that the method simply falls back to returning the size of fetch(). For large result sets this may come at a severe performance penalty. For very specific domain models where fetchResults() has to be used in conjunction with complex queries containing multiple group by elements and/or a having clause, we recommend using the Blaze-Persistence integration for QueryDSL. Among other advanced query features, Blaze-Persistence makes it possible to select from subqueries in JPQL. As a result the BlazeJPAQuery provided with the integration, implements fetchResults properly and always executes a proper count query. Mind that for any scenario where the count is not strictly needed separately, we recommend to use fetch() instead.

fetchResults는 계산을 위해 카운트 쿼리가 필요합니다.

Querydsl-sql에서는 쿼리를 서브쿼리로 래핑하여 이 작업을 수행합니다. 다음과 같이 원래의 쿼리를 사용하여 COUNT(*) FROM (<original query>)와 같이 표현됩니다. 안타깝게도 JPA의 쿼리 언어인 JPQL은 서브쿼리에서 프로젝트를 허용하지 않습니다. 결과적으로 JPQL에서 카운트 쿼리를 표현하는 통일된 방법이 없습니다.

역사적으로 QueryDSL은 결과 수를 계산하기 위해 수정된 쿼리를 생성하려고 노력했습니다.

그러나 이 접근 방식은 간단한 쿼리에만 작동합니다. 특히 여러 개의 그룹화 조건이 있는 쿼리나 having 절이 있는 쿼리는 문제가 발생할 수 있습니다. 이는 대부분의 방언에서 유효한 SQL이지만 JPQL에서는 유효하지 않은 COUNT(DISTINCT a, b, c) 때문입니다. 또한 having 절은 선택 요소나 집계 함수를 참조할 수 있으며 따라서 이를 where 절로 옮겨서 시뮬레이트할 수 없습니다. 여러 그룹화 요소나 having 절이 있는 쿼리에 대한 fetchResults를 지원하기 위해 우리는 메모리에서 카운트를 생성합니다. 이는 메서드가 단순히 fetch()의 크기를 반환하도록 되돌아가는 것을 의미합니다.

대규모 결과 집합의 경우 성능에 심각한 페널티가 발생할 수 있습니다. 여러 그룹화 요소나 having 절이 포함된 복잡한 쿼리와 함께 fetchResults()를 사용해야 하는 매우 구체적인 도메인 모델의 경우, QueryDSL에 대한 Blaze-Persistence 통합을 사용하는 것이 좋습니다. Blaze-Persistence는 JPQL에서 서브쿼리를 선택할 수 있도록 하는 고급 쿼리 기능 중 하나입니다.

결과적으로 통합에서 제공하는 BlazeJPAQuery는 fetchResults를 올바르게 구현하고 항상 적절한 카운트 쿼리를 실행합니다. 카운트가 별도로 엄격하게 필요하지 않은 모든 시나리오에서는 fetch()를 대신 사용하는 것이 좋습니다.

 

 

결론: fetch() 를 써라

'JPA' 카테고리의 다른 글

연관관계  (0) 2023.06.20
JPA (1) - JPA 란?  (0) 2021.12.22
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/07   »
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
글 보관함