문제 상황
Querydsl을 통해 MySQL에 날짜 함수를 적용하려고 하는데 이슈가 있었다.
날짜 함수를 적용하기 위해서는 Expressions.stringTemplate 을 이용하면 원하는 mysql 함수를 적용시킬 수 있다고 생각했다.
날짜 연산이 들어간 조건문을 만들어 디버깅을 하는데 해당 조건을 인식할 수 없다고 에러가 발생했다.
reason
Hibernate에서 아직 INTERVAl 예약어를 지원하지 않는다.
QueryDsl 코드는 컴파일 이후 Hibernate로 변경되어 실행되므로, Hibernate에서 지원하지 않는 예약어는 사용할 수 없다!!
(Querydsl은 HQL(Hibernate Query Language) 쿼리를 Type-Safe 하게 유지보수해야 할 필요로 탄생했다.)
Querydsl 실행 과정
- Querydsl로 작성한 JAVA 쿼리는 JPQL로 변환됩니다.
- 이를 Hibernate가 데이터베이스에 맞는 SQL로 변환하여 실행합니다.
- 이 과정에서 Hibernate는 쿼리 실행과 데이터 매핑을 처리합니다.
- 변환된 쿼리는 JPA(Hibernate)나 JDBC를 통해 실행됩니다.
- Hibernate는 ORM을 통해 데이터를 Java 객체로 매핑하며, JDBC는 SQL 쿼리를 직접 실행하고 결과를 반환합니다.
example.startAt.between(
Expressions.stringTemplate("date_format(DATE_ADD({0}, INTERVAL 110 MINUTE), '%H:%i')", baseDateTime),
Expressions.stringTemplate("date_format(DATE_ADD({0}, INTERVAL 130 MINUTE), '%H:%i')", baseDateTime)
))
해결 방법
INTERVAl 예약어 사용을 할 수 없으므로, Java에서 제공하는 date Util을 사용합니다.
sr.startAt.between(
baseDateTime.plusMinutes(110),baseDateTime.plusMinutes(130));
내가 필요한 함수는 현재 시간에 110, 130분을 더하는 함수였다. 이를 plus, plusMinutes 메서드를 사용해 간단하게 처리할 수 있었다.
DatetimeFormatter.ofPattern()을 통해 원하는 date 형식으로 변환하여 Querydsl에서 값을 비교할 수 있습니다.
느낀점
디버깅을 통해 에러가 발생하는 부분을 확인하고 hibernate로 실행되는 쿼리를 실제 Mysql console에서 실행해 보며 쿼리 문제인지 호환성 문제인지 확인할 수 있었습니다.
mysql에서는 제대로 동작하는 것을 확인한 후, querydsl과 hibernate 공식문서를 찾아보니 지원하지 않는 예약어임을 확인하였습니다.
에러가 발생할 때는 진짜 침착하게 에러 메시지를 읽고 문제를 확인한 다음에, 공식문서나 스택 오버 플로우를 먼저 찾아보는 게 효율적인 방법임을 느꼈습니다.
📌 깨달은 점
인턴을 진행하면서 첫 작업이 파이썬 코드를 자바로 옮기는 작업을 진행했었다.
마이그레이션 작업 중에 내가 옮기는 코드에 문제가 생기지 않기 위해, 최대한 이전 코드와 유사하게 작업하려고 했다.
작업을 하면서 사수분께 많은 조언을 듣고 자바 프로그래밍에 맞게 리팩터링 하면서, 리팩토링 작업을 진행할 때 기존 코드와 유사하게 옮기기보다는 유지보수와 확장성이 좋게 작업하는 것이 중요함을 알게 되었다.
감사합니다. 사수님!!
참고자료
'Spring Framework > QueryDSL' 카테고리의 다른 글
Spring MongoDB 환경 QueryDSL 설정하기 (0) | 2025.01.02 |
---|---|
Querydsl OrderSpecifier를 활용한 동적 정렬 방법 - Pathbuilder, Sort (0) | 2024.10.18 |
[Querydsl] JPAExpressions를 활용한 Querydsl 서브쿼리 작성 방법 (0) | 2024.10.17 |
[Querydsl] QueryDSL @QueryProjection 프로젝션 활용법 : DTO, Bean, Field, Constructor 사용법 (0) | 2024.09.16 |
[QueryDsl] QueryDsl groupBy 여러 개 적용하기 (0) | 2024.08.10 |