nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: expecting CLOSE, found ',' near line 1, column 46 [select count(distinct Activity.id, Activity.activityDate)
org.hibernate.hql.internal.ast.QuerySyntaxException: expecting CLOSE, found ',' near line 1, column 46 [select count(distinct Activity.id, Activity.activityDate)
왜 이러세요... 😭
@Override
public Page<yearActivityListDTO> findMonthListWithActivity(Pageable pageable){
BooleanBuilder builder = new BooleanBuilder();
builder.and(Activity.activityDate.between(current.minusYears(1), current));
current.toLocalDate();
final JPQLQuery<yearActivityListDTO> query = from(Activity)
.where(builder)
.select(new QyearActivityListDTO(Activity.activityDate, Activity.farm.id, Activity.value.sum()));
List<yearActivityListDTO> result = getQuerydsl().applyPagination(pageable, query).fetch();
return new PageImpl<>(result, pageable, query.fetchCount());
}
이 코드는 잘 실행된다. 여기서 groupBy
조건이 필요해서 추가했더니
다음과 같은 오류가 발생했다. 처음엔 groupBy
가 2개 이상의 인자는 받지 않는다고 생각하고
'groupBy multiple' 과 같이 검색해가며 찾아보았더니 groupBy(x, y)
는 맞게 쓴거였다. 디버깅해보니 쿼리문은 정상적으로 데이터를 가져오고 있었다.
오류 메세지에서는 사실 groupBy 라인이 아니라 아래쪽에 페이징을 위한 return 라인을 가리키고 있었다. IDE 오류 메세지 믿을걸 groupBy(x)로 바꾸면 잘 되길래 groupBy 문제인줄
혹시나 해서 Querydsl repository issue 에 방문해 보았더니...
이미 논의 중이던 문제였고 아직까지도 해결되지 못한 문제로 남아있는 것 같다.
근데 이슈는 닫혀있음 뭐지?
정리해보면, groupBy(x, y)
와 fetchResults()
, fetchCount()
를 같이 사용하면 오류가 발생한다.
👉 https://github.com/querydsl/querydsl/issues/2504
👉 https://github.com/querydsl/querydsl/pull/2605
위 링크로 가보면 같은 문제로 고통을 호소하는 개발자들을 볼 수 있다..
깃허브를 확인한 후 오류 메세지를 구글링 해봤는데 나랑 같은 문제를 겪는 사람들의 글을 볼 수 있었다. groupBy에 꽂혀서 오류 메세지 검색할 생각을 못했다. 아니었으면 삽질을 덜 했을텐데...
return new PageImpl<>(result, pageable, result.size());
위와 같이 쿼리의 개수를 셀 수 있게 쿼리의 결과 리스트의 사이즈를 넣어주면 된다고 생각했다.
실행해보니 오류는 없었지만 데이터가 pagination size를 5라고 했다고 하면 딱 5개만 출력되었다. 덕분에 쿼리의 결과가 리스트에 한번에 저장되는게 아니라는 사실을 알게 되었다. (정상적으로 출력되면 33페이지까지 존재해야한다)
다른 사람들의 해결방식을 보니 코드를 아예 다시 써야하는 수준이었다. JPA -> Mybatis로 옮길 생각을 하는 사람도 보았다. 일단 pagination은 혹시 필요할까봐 작성한 것이었기 때문에 포기한 채 원하는 데이터만 잘 가져오도록 하기로 했다.
@Override
public List<yearActivityListDTO> findMonthListWithActivity() {
BooleanBuilder builder = new BooleanBuilder();
builder.and(Activity.activityDate
.between(
LocalDateTime.now().minusYears(1),
LocalDateTime.now()
));
return from(Activity)
.where(builder)
.select(new QyearActivityListDTO(Activity.activityDate.yearMonth(), Activity.farm.id ,Activity.value.sum()
))
.groupBy(Activity.farm, Activity.activityDate.yearMonth())
.fetch();
}
page 기능이 필요해지면 다른 방식으로 pagination 할 수 있는 방법을 찾아보고 적용시킬 예정이다. pagination하는 방법은 다양했던 걸로 기억하기 때문에 fetchCount()를 쓰지 않아도 될지도..