본문 바로가기

Spring

QueryDSL 삽질기

QueryDSL을 이용해서 전체리스트를 뿌려주는 쿼리를 작성하고 있었고, 해당 쿼리는 페이징이 들어가야했다.

 

작성을 완료한 후!  잘되었겠지 하고 실행 ... postman으로 요청을 보냈다... 

 

BUT ,,,,

expectin CLOSE, found '(' ...

 

내가 잘못 작성을 한 것 일까?  다시 한번 보았지만 이상한 부분은 없었다.

 

무슨 문제가 있는거지 열심히 검색을 하였다.

 

 

 

일단 내가 작성한 쿼리에는 GroupBy 가 들어가 있고, 페이징에 전체 리스트의 갯수를 구하기위해 fetchCount() 를 실행한 쿼리였다.

 

그러다 발견한 글은 

 

https://github.com/querydsl/querydsl/issues/1614

 

JPA fetchCount() and group by not working · Issue #1614 · querydsl/querydsl

This is a bug resulting from this posting on Google Groups (see https://groups.google.com/forum/#!topic/querydsl/WH582YIY98I): I found a strange problem with a rather complex group by query when it...

github.com

 

나와 같은 고통을 호소하고있는 글 이었다.

 

글의 내용을보니 나와 완전 똑같이 GroupBy를 한후 fetchCount를 하였는데 오류가 발생한다는 글이었다.

 

5년전에 등록된 이슈 였는데 아직까지 해결이 안된 모양이다... 아래 개발자 분도 고통을 호소하고있다.

 

QueryDSl 오픈소스에 많은 기여를 한 개발자 분깨서 답변을 남겨주셨다. 치명적 이슈가 있어서 아직까지 해결이 안된것 같다.

 

그래서 나는 QueryDSL로 해결을 하면 안될것 같다 생각을 하고, 다른 방법이 모가있을까 생각을 하였다.

 

1. 지금 문제는 페이징할 리스트의 전체 갯수를 구하지못하는 상황이니, 전체 갯수만 NativeQuery로 구하자

2. MyBatis로 바꾼다.

3. 이 부분만 Criteria로 바꿔서 해보자 였다.

 

내가 판단하기엔 MyBatis로 바꾸면 시간이 너무 오래 걸리니, 후에 바꾸고, 지금은 페이징이 되도록 기능을 구현하자였다.

 

그래서 3번 선택지인 criteria로 바꿔서 코드를 작성하였다.

 

열심히 criteria로 바꾸었고, 이제 대망의 페이징만 구현하면 끝!

 

기쁨도 잠시 criteria도 비슷한 문제에 직면하게되었다. 전체 리스트의 갯수가 구해지지 않는것이였다. 해당 쿼리에 대해서 `.getSingleResult` 를 통해서 전체 갯수를 구하면 되는데 , 마음대로 작동하지 않았다.... ( 너무 조급해서 그랬나 아마 지금 다시 작성해보면 될 것 같기도... )

 

그래서 빠르게 버리고 전체 갯수를 구한 후 페이징을 구현해주는 방식으로 하자라고 마음을 먹었다.

 

 

그러다 든 생각이 어차피 전체 갯수만 구하면 되니까 groupBy말고 distict로 중복을 걸러서 전체 갯수만 구하면되지 않을까? 였다.

 

But,,

 

문제는 또 다시 발생하였다. 내가 원하는 쿼리는 groupBy에 두가지 조건이 들어가야했고, QueryDSL은 멀티 distict 기능을 지원하지 않는다는것이었다.

 

구글링을 해보니 이는 QueryDSL에서의 문제가 아니라 JPA에서 2개이상의 distinct를 제한해서 해당기능은 지원을 하지 않는다고 한다.

 

 

 

 

그래서 해당방법도 버리고 빠르게 NativeQuery로 전체 갯수를 구하는 방식으로 바꿨다.

 

 

이번일을 계기로 몇가지 궁금증이 생기게되었다.

 

1. JPA는 왜 multi distict 같은 기능에 제한을 두었을까? 

2. 무슨이유때문에 QueryDSL 오픈소스 컨트리뷰터는 단순 JPA로는 구현을 할 수 없다 라고 한걸까? 

 

JPA에 대해서 깊게 공부 한번 해보아야겠다!