QueryDSL 의 조회 결과가 이상합니다.

24.05.10 17:16 작성 조회수 34

0

오늘 날짜 기준으로 지난 예약건들을 조회하고 싶어서 QueryDSL 을 사용하게 되었는데
조회 결과가 이상하게 나와서 질문 올립니다.

 

INSERT INTO Reservation (client_id, guide_id, name, reservated_at)
VALUES
    (1, 2, 'Reservation -1Y', DATETIME('now', '-1 years')),
    (1, 2, 'Reservation -72', DATETIME('now', '-3 days')),
    (1, 2, 'Reservation -48', DATETIME('now', '-2 days')),
    (1, 2, 'Reservation -20', DATETIME('now', '-20 hours')),
    (1, 2, 'Reservation -16', DATETIME('now', '-16 hours')),
    (1, 2, 'Reservation -12', DATETIME('now', '-12 hours')),
    (1, 2, 'Reservation -8', DATETIME('now', '-8 hours')),
    (1, 2, 'Reservation -4', DATETIME('now', '-4 hours')),
    (1, 2, 'Reservation now', CURRENT_TIMESTAMP),
    (1, 2, 'Reservation +4', DATETIME('now', '+4 hours')),
    (2, 1, 'Reservation +8', DATETIME('now', '+8 hours')),
    (2, 1, 'Reservation +12', DATETIME('now', '+12 hours')),
    (1, 2, 'Reservation +16', DATETIME('now', '+16 hours')),
    (1, 2, 'Reservation +20', DATETIME('now', '+20 hours')),
    (1, 2, 'Reservation +48', DATETIME('now', '+2 days')),
    (1, 2, 'Reservation +120', DATETIME('now', '+5 days'));

해당 쿼리를 통해 데이터를 삽입하였으며,
삽입된 날짜 데이터는 [2024-05-10 03:57:51] 이렇게 들어가있습니다.

 

Hibernate: 
    select
        r1_0.id,
        r1_0.client_id,
        r1_0.guide_id,
        r1_0.name,
        r1_0.reservated_at 
    from
        reservation r1_0 
    where
        r1_0.reservated_at<?
2024-05-10T16:57:52.472+09:00 TRACE 20848 --- [    Test worker] org.hibernate.orm.jdbc.bind              : binding parameter (1:TIMESTAMP) <- [2024-05-10T16:57:52.185060600]

 

우선 공통적으로 모든 쿼리들의 로그는 위와 같습니다. 하지만 해당 결과로는 0 건이 조회됩니다.

SELECT
    r1_0.id,
    r1_0.client_id,
    r1_0.guide_id,
    r1_0.name,
    r1_0.reservated_at
FROM
    reservation r1_0
WHERE
    r1_0.reservated_at > '2024-05-10T16:57:52.185060600';


위와 같이 진행했을 때에는 T 때문인지 5월 11일 이후의 데이터들만 조회되고

SELECT
    r1_0.id,
    r1_0.client_id,
    r1_0.guide_id,
    r1_0.name,
    r1_0.reservated_at
FROM
    reservation r1_0
WHERE
    r1_0.reservated_at > '2024-05-10 16:09:14.649686900';


위와 같이 진행했을 때에는 시간에 맞게 잘 조회되는 모습입니다.

 

        return queryFactory
                .selectFrom(reservation)
                .where(reservation.reservatedAt.lt(LocalDateTime.now()))
                .fetch();

        return queryFactory
                .selectFrom(reservation)
                .where(reservation.client.id.eq(clientId)
                        .and(reservation.reservatedAt.before(LocalDateTime.now())))
                .fetch();

위 처럼 QueryDSL 을 사용하였을 때도 처음 로그가 발생하며 데이터가 0개 조회되고

List<Reservation> findByClientIdAndReservatedAtBefore(Long client_id, LocalDateTime reservatedAt);
    List<Reservation> findByClientIdAndReservatedAtLessThanEqual(Long client_id, LocalDateTime reservatedAt);

JPA 를 사용하였을 때도 마찬가지로 동일한 로그와 0건의 데이터가 조회됩니다.

도대체 뭐가 문제인지 모르겠습니다...

참고로 엔티티에서 reservatedAt 은 LocalDateTime 으로 설정하였습니다.

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.05.11

안녕하세요, 인프런 AI 인턴입니다.

특별한 몽구스님의 질문과 관련하여, QueryDSL을 사용하여 과거 데이터를 조회하는 과정에서 예상과 다른 결과가 발생하는 상황을 봤습니다. 문제를 해결하기 위해 몇 가지 점검해야 할 사항에 대해 말씀드리겠습니다.

  1. 시간대 처리: LocalDateTime.now()를 사용할 때, 기본적으로 시스템의 기본 시간대를 사용합니다. 데이터베이스에 저장된 시간과 애플리케이션의 시간대가 다를 경우, 예상치 못한 결과가 발생할 수 있습니다. 데이터베이스와 애플리케이션 모두에서 사용하는 시간대가 동일한지 확인해보세요.

  2. 타임스탬프 포맷: SQL 쿼리에서 직접 작성한 예제에서 ’T’ 문자를 사용하고 있으며, 이로 인해 조회 결과가 달라지는 경우가 있습니다. 데이터베이스에 저장된 타임스탬프의 포맷과 쿼리에서 사용하는 포맷이 일치하는지 확인해 보세요. 일부 데이터베이스는 ISO 8601 포맷(2024-05-10T16:57:52.185060600)을 정상적으로 파싱하지 못할 수도 있습니다.

  3. JPA 및 QueryDSL 설정 확인: LocalDateTime 타입을 사용할 때 JPA 및 QueryDSL의 날짜 및 시간 처리 방법이 올바르게 설정되어 있는지 확인하세요. 특히, @Column 어노테이션에서 columnDefinition을 사용하여 타입을 명시적으로 지정했는지 확인해 보세요.

  4. 데이터베이스 로그: 실제 데이터베이스에서 실행되는 쿼리 로그를 확인하여, 애플리케이션으로부터 전달된 쿼리가 데이터베이스에서 어떻게 실행되는지 확인해 보세요. 때로는 애플리케이션에서 의도한 바와 다르게 쿼리가 구성되어 전달되는 경우가 있습니다.

  5. 예약된 시간(ReservatedAt) 데이터 확인: 데이터베이스에 실제로 저장된 ReservatedAt 필드의 값이 기대하는 형식과 값으로 저장되어 있는지 확인해 보세요. 데이터 삽입 과정에서의 문제나 변환 문제로 인해 예상과 다른 값이 저장되었을 수도 있습니다.

이러한 체크 리스트를 통해 문제의 원인을 좁혀볼 수 있을 것입니다. 각각의 확인 사항을 검토해보시고, 그래도 문제가 해결되지 않는다면 데이터베이스와 JPA, QueryDSL 설정의 상세한 정보와 함께 다시 질문해 주세요.