PostgreSQL은 null을 받지 못한다?

김영준·2026년 4월 20일

멜로미

목록 보기
12/13

< 기존 인기순 쿼리 >

  @Query("""                        
      SELECT p FROM TherapyPost p
      WHERE p.deletedAt IS NULL
        AND (:cursorScore IS NULL OR
             p.popularityScore < :cursorScore OR
             (p.popularityScore = :cursorScore AND p.id < :cursorId))
      ORDER BY p.popularityScore DESC, p.id DESC
      """)
  List<TherapyPost> findFeedPopular(
      @Param("cursorScore") Long cursorScore,
      @Param("cursorId") Long cursorId,
      Pageable pageable
  );

cursorScore이 없으면 바로 true 되는거로 생각되었는데 첫 페이지에 제대로 반영 못함.

< Hibernate가 PostgreSQL에 보내는 실제 SQL >

 SELECT * FROM therapy_posts
  WHERE ($1 IS NULL OR popularity_score < $1)

:cursorScore 같은 이름 있는 파라미터가 $1, $2 같은 위치 기반 바인딩 변수로 바뀜. 만약 여기에 150 이 들어가게 된다면 $1은 Int네? 라고 판단하게됨. 근데 null을 보면 이게 어떤 타입인지 PostgreSQL은 판단할 수 없는거임
그래서 여기서 500 에러를 내는거임

그래서 아래와 같이 수정

  // null을 아예 안 넘김
  if (popCursor == null) {
      // 첫 페이지 → WHERE절에 커서 조건 자체가 없는 쿼리 호출
      repo.findFeedPopular(limit);
  } else {
      // 다음 페이지 → non-null 값만 넘김, PostgreSQL이 타입 추론 가능
      repo.findFeedPopular(popCursor.score(), popCursor.id(), limit);
  }

즉, null을 넘기지 않도록 쿼리를 다시 작성. 기존 4개의 쿼리였다면 지금은 분기처리로 인해 8개 쿼리이긴함.

profile
개발의 신이 될거다

0개의 댓글