[Spring]무한 스크롤 + Enum 정렬 트러블슈팅
intro
- 프로젝트를 진행하며 발생한 문제 상황과 해결 과정들을 상세히 기록하고 추후에 같은 문제가 발생 했을때 빠르게 문제 해결하기 위해 트러블 슈팅을 정리할려고 한다.
- 기록하는 습관을 기르기 위해 프로젝트 기간동안 꾸준히 작성할 것 이다.
배달 앱에서 메뉴 리스트를 무한 스크롤 방식으로 보여주기 위해 커서 기반 페이징을 도입했다. 하지만 카테고리 정렬, enum 사용, JPQL 커서 조건 등 다양한 문제에 부딪혔다.
⚠️ 1.문제 상황 발생
JPQL 을 이용하여 커서 기반 페이지네이션을 작성했다. JPQL에서 enum 메서드 사용 불가하여 오류가 발생했다.
Category.Enum
public enum Category {
MAIN_MENU(1),
SIDE_MENU(2),
DRINK(3);
private final int sortOrder;
Category(int sortOrder) {
this.sortOrder = sortOrder;
}
MenuRepository 조회 - jpql 쿼리
@Query("""
SELECT m FROM Menu m
WHERE m.category.sortOrder > :categoryCursor
ORDER BY m.category.sortOrder ASC, m.createdAt DESC
""")

🔎 2.원인 추론
@Query("""
SELECT m FROM Menu m
WHERE m.category.sortOrder > :categoryCursor
ORDER BY m.category.sortOrder ASC
""")
찾아보니 sortOrder는 Enum 내부 필드이므로 JPQL에서 접근할 수 없다
→ JPQL은 Enum의 내부 메서드, 필드를 지원하지 않음.
📝 3.해결방안
EnumType.ORDINAL로 DB 저장 방식을 변경했다.
@Enumerated(EnumType.ORDINAL)
private Category category;
- Enum이 0, 1, 2...로 DB에 저장된다
- 정렬 및 비교가 가능해짐 (m.category > :categoryCursor)
📌4.결과 확인
최종 JPQL 쿼리
@Query("""
SELECT m FROM Menu m
WHERE (:categoryCursor IS NULL
OR m.category > :categoryCursor
OR (m.category = :categoryCursor AND m.id > :lastId))
ORDER BY m.category ASC, m.id ASC
""")
정렬 기준을 category(ordinal) → id 순으로 설정해 무한 스크롤 시 데이터가 중복되거나 누락되지 않도록 하였다.
결과창

✒️회고
- 이번 트러블슈팅을 통해 JPQL에서는 Enum의 내부 필드나 메서드에 직접 접근할 수 없다는 점을 처음으로 명확히 알게 되었다.
- 평소 자바 코드에서는 자연스럽게 사용하던 getSortOrder()를 JPQL에서도 당연히 될 거라고 생각했지만, 실제로는 그게 아니었다.
- @Enumerated(EnumType.ORDINAL) 설정을 통해 enum 순서를 기준으로 정렬이 가능하게 만들었고, 이 덕분에 무한 스크롤 구현에 필요한 커서 기반 페이지네이션 로직도 깔끔하게 해결할 수 있었다.
- 앞으로는 JPQL을 작성할 때 enum 필드를 사용하게 된다면 반드시 DB 저장 방식부터 확인하고, ORDINAL이나 STRING 사용에 따라 쿼리 설계를 신중하게 해야겠다.