
@Query("SELECT latestcommute FROM Commute latestcommute
WHERE latestcommute.member.id = :memberId AND latestcommute.createdAt =
(SELECT MAX(commute.createdAt) FROM Commute commute
WHERE commute.member.id = :memberId)")

📌 서브 쿼리를 이용해 가장 최근 기록을 가져오셨군요! 생각하지 못한 방법 또 하나 배우고 갑니다! 😊
추가로 질문을 드리자면 저 같은 경우는 서브쿼리는 성능이 걱정되어 불가피한 상황이 아닌 경우에는 지양하는 편인데 영훈님은 어떻게 생각하시는지 궁금합니다...!
Join ORDER BY LIMIT 으로 변경@Query("SELECT latestcommute FROM Commute latestcommute
JOIN latestcommute.member member
WHERE member.id = :memberId
ORDER BY latestcommute.createdAt DESC")
@Query("SELECT latestcommute FROM Commute latestcommute
JOIN latestcommute.member member
WHERE member.id = :memberId
ORDER BY latestcommute.createdAt DESC")
List<Commute> findFirstByMemberId(long MemberId);
# 실제 쿼리 조회
Hibernate:
select
c1_0.id,
c1_0.attendance,
c1_0.start_of_work,
c1_0.member_id,
c1_0.end_of_work
from
commute c1_0
join
member m1_0
on m1_0.id=c1_0.member_id
where
m1_0.id=?
order by
c1_0.start_of_work desc
Service 단에서 처리하려다, 모든 List를 받아오는것이 마음에 들지 않아서 JPA에 대해 조금 더 찾아보았습니다.LIMIT을 지원하지 않는데, 굳이 JPQL을 사용할 이유가 없었습니다.Optional<Commute> findFirstByMemberIdOrderByCreatedAtDesc(Long memberId);
Hibernate:
select
c1_0.id,
c1_0.attendance,
c1_0.start_of_work,
c1_0.member_id,
c1_0.end_of_work
from
commute c1_0
left join
member m1_0
on m1_0.id=c1_0.member_id
where
m1_0.id=?
order by
c1_0.start_of_work desc
limit
?
💡 서브쿼리를 사용하지 않고,
Left Join을 통해 최근순으로 정렬하고,
LIMIT을 통해 제일 처음(가장 최근)Commute을 반환합니다.
public record startOfWorkRequest(@NotNull long id) {
public Commute toEntity(Member member){
return Commute.builder()
.member(member)
.build();
}
}

📌 요청값 검증 처리를 위해
@NotNull등 어노테이션을 사용하고 계신데,
요청값에 대해 예외가 발생하면 어떤식으로 응답이 나가는지 알고 계신가요?
몇몇 커스텀 예외에 대해 핸들링 해서 일관된 응답 형식으로 응답이 나가고 있는데,
요청값 검증 예외는 다른 형식으로 응답이 나갈것 같습니다.
Edge-Case의 Exception을 우선적으로 설정하느라 @Valid 로 값 검증을 하고 있으면서도
ExceptionHandler 에서 정작 ValidException 처리하는 메서드를 만들어 놓지 않았다는걸 깨달았습니다.
따로 ValidException 처리를 하지 않았기때문에, 요청값 검증 예외가 발생한다면,
전부 500 Internal-server-error로 처리 되었을 것입니다.
@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<ErrorResponse> handle(MethodArgumentNotValidException e){
e.getStackTrace();
log.error("MethodArgumentNotValidException", e);
return createErrorResponse(ErrorCode.INVALID_INPUT_VALUE);
}

💡
MethodArgumentNotValidException예외가 발생한다면,
400 Bad Request와 올바르지 않은 입력값이라는 메세지가 출력되도록 했습니다.