-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: 최신순으로 리뷰를 조회하는 쿼리문 수정 #34
Conversation
Test Results0 tests 0 ✅ 0s ⏱️ Results for commit 70d2d29. ♻️ This comment has been updated with latest results. |
@@ -87,7 +87,8 @@ private static Predicate checkEquals(final String fieldName, | |||
if (LOCALDATETIME_TYPE_INCLUDE.contains(fieldName)) { | |||
final Path<LocalDateTime> createdAtPath = root.get(fieldName); | |||
final LocalDateTime lastReviewCreatedAt = lastReview.getCreatedAt(); | |||
return criteriaBuilder.equal(createdAtPath, lastReviewCreatedAt); | |||
final int reformatNano = Math.round((float) lastReviewCreatedAt.getNano() / 1000) * 1000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nanoseconds가 1e-9이므로 데이터베이스 형식과 동일하게 1e-6까지만 보이게하고, 나머지는 반올림하도록 변경했습니다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
너무 좋네요 미친 분석 마음에 듭니다
수고했어 로우건
Issue
✨ 구현한 기능
created_at
값을 데이터베이스에 맞게 microseconds로 단위를 수정했습니다.Thread.sleep(...)
을 삭제 했습니다.📢 논의하고 싶은 내용
🎸 기타
삽질을 해보면서 확인해보니
복수_리뷰_저장(...)
이후entityManager.clear()
를 호출하냐, 안하냐에 따라서 쿼리문이 달라집니다.entityManager.clear()
를 호출하지 않았을 경우검색 쿼리문에 들어가는 영속성 컨텍스트의 1차 캐시에 있던
review3
이 그대로 재사용됩니다. 로그 살펴보면 리뷰에 대한 select문 없이 insert문만 존재합니다.(인텔리제이에서 디버그 모드로 실행해보면 완전히 같은 객체임을 확인 가능함)
entityManager.clear()
를 호출 했을 경우이때는 1차 캐시를 지웠으니 당연히 디비에 있는 값을 꺼내옵니다. 로그를 살펴보면 리뷰에 대한 select문이 존재합니다.
?. 소수점 9자리와 소수점 6자리 차이가 나는 이유
Java의 LocalDateTime은 LocalDate와 LocalTime을 합쳐서 사용합니다.
LocalTime 값을 확인해보면 nanoseconds가 9자리의 수까지 가능합니다.
H2 공식 문서를 보면 TIMESTAMP는 소수점 0자리 수부터 9자리 수까지 제공하지만, 기본값은 6입니다.
테이블 생성 쿼리를 확인해보면 TIMESTAMP(6)으로 저장하는 것을 확인할 수 있습니다.
참고로 MySQL 공식문서도 최대 소수점 아래 6자리까지만 지원한다고 나와있습니다.
테스트가 실패하는 이유
1차 캐시에서 가져오는 값은 26.362916145초이지만, 디비에서 가져오는 값은 26.362916초이기 때문에 쿼리문은
26.362916145 > created_at (26.362916)
으로 동작하므로 자기자신의 값까지 가져오게 됩니다.현재 서비스에서는 리뷰 작성 API, 리뷰 조회 API 가 분리되어 서로 다른 트랜잭션을 사용하지만, 테스트 코드 한정에서만 같은 트랜잭션 범위 내에서 저장과 조회가 동작하여 발생하는 문제입니다.
테스트가 성공하는 이유
H2 공식문서에서 설정된 값보다 더 깊이 들어간 소수점 자리수는 반올림을 한다고 나와있습니다.
위와 같이 적용되기 때문에
26.362909999 > created_at (26.362910)
는 성립하지 않으므로 정상적인 값이 나오게 됩니다.⏰ 일정