Skip to content
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

Merged
merged 2 commits into from
Apr 4, 2024

Conversation

70825
Copy link
Member

@70825 70825 commented Apr 4, 2024

Issue

✨ 구현한 기능

  • 최신순으로 리뷰를 정렬하는 created_at 값을 데이터베이스에 맞게 microseconds로 단위를 수정했습니다.
  • 테스트 코드에 있는 Thread.sleep(...)을 삭제 했습니다.

📢 논의하고 싶은 내용

  • .

🎸 기타

삽질을 해보면서 확인해보니 복수_리뷰_저장(...) 이후 entityManager.clear()를 호출하냐, 안하냐에 따라서 쿼리문이 달라집니다.

  1. entityManager.clear()를 호출하지 않았을 경우

스크린샷 2024-04-03 오전 12 14 00

검색 쿼리문에 들어가는 영속성 컨텍스트의 1차 캐시에 있던 review3이 그대로 재사용됩니다. 로그 살펴보면 리뷰에 대한 select문 없이 insert문만 존재합니다.
(인텔리제이에서 디버그 모드로 실행해보면 완전히 같은 객체임을 확인 가능함)

  1. entityManager.clear()를 호출 했을 경우

스크린샷 2024-04-03 오전 12 16 39

이때는 1차 캐시를 지웠으니 당연히 디비에 있는 값을 꺼내옵니다. 로그를 살펴보면 리뷰에 대한 select문이 존재합니다.

?. 소수점 9자리와 소수점 6자리 차이가 나는 이유

스크린샷 2024-04-03 오전 12 20 35

Java의 LocalDateTime은 LocalDate와 LocalTime을 합쳐서 사용합니다.

스크린샷 2024-04-03 오전 12 19 45

LocalTime 값을 확인해보면 nanoseconds가 9자리의 수까지 가능합니다.

스크린샷 2024-04-03 오전 12 22 10

H2 공식 문서를 보면 TIMESTAMP는 소수점 0자리 수부터 9자리 수까지 제공하지만, 기본값은 6입니다.

스크린샷 2024-04-03 오전 12 23 10

테이블 생성 쿼리를 확인해보면 TIMESTAMP(6)으로 저장하는 것을 확인할 수 있습니다.

image

참고로 MySQL 공식문서도 최대 소수점 아래 6자리까지만 지원한다고 나와있습니다.

테스트가 실패하는 이유

1차 캐시에서 가져오는 값은 26.362916145초이지만, 디비에서 가져오는 값은 26.362916초이기 때문에 쿼리문은 26.362916145 > created_at (26.362916)으로 동작하므로 자기자신의 값까지 가져오게 됩니다.

현재 서비스에서는 리뷰 작성 API, 리뷰 조회 API 가 분리되어 서로 다른 트랜잭션을 사용하지만, 테스트 코드 한정에서만 같은 트랜잭션 범위 내에서 저장과 조회가 동작하여 발생하는 문제입니다.

테스트가 성공하는 이유

스크린샷 2024-04-03 오전 12 34 18

H2 공식문서에서 설정된 값보다 더 깊이 들어간 소수점 자리수는 반올림을 한다고 나와있습니다.

  • 실제 값: 26.362909999초
  • 저장 값: 26.362910초

위와 같이 적용되기 때문에 26.362909999 > created_at (26.362910)는 성립하지 않으므로 정상적인 값이 나오게 됩니다.

⏰ 일정

  • 추정 시간 : 코드 삭제하려고 했음
  • 걸린 시간 : 하루

@70825 70825 added the 🐛 Bug label Apr 4, 2024
@70825 70825 self-assigned this Apr 4, 2024
@70825 70825 changed the title fix: 최신순 시간을 nanoseconds에서 microseconds로 변경 최신순으로 리뷰를 조회하는 쿼리문 수정 Apr 4, 2024
Copy link

github-actions bot commented Apr 4, 2024

Test Results

0 tests   0 ✅  0s ⏱️
0 suites  0 💤
0 files    0 ❌

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;
Copy link
Member Author

@70825 70825 Apr 4, 2024

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까지만 보이게하고, 나머지는 반올림하도록 변경했습니다

Copy link
Contributor

@wugawuga wugawuga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

너무 좋네요 미친 분석 마음에 듭니다
수고했어 로우건

@70825 70825 changed the title 최신순으로 리뷰를 조회하는 쿼리문 수정 fix: 최신순으로 리뷰를 조회하는 쿼리문 수정 Apr 4, 2024
@70825 70825 merged commit 3d54595 into develop Apr 4, 2024
3 checks passed
@70825 70825 deleted the fix/issue-33 branch April 4, 2024 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

최신순으로 리뷰를 조회하는 쿼리문 수정
2 participants