[에러]
현재 user가 특정 도서관에서 책을 대여하는데 최대 5권까지 대여가 가능한 조건을 걸어뒀다.
int rentalHistoryCount = memberBookRepository.countByMember(targetMember);
if (rentalHistoryCount >= 5) {
throw new BusinessLogicException(ExceptionCode.MAXIMUM_RENTAL_ALREADY);
}
targetLibraryBook.setBookStatus(Book.BookStatus.UNAVAILABLE);
libraryBookService.saveLibraryBook(targetLibraryBook);
countByMember()메서드는 Spring Data JPA에서 제공하는 자동 메서드 형태로
파라미터로 주어지는 member객체가 가진 MemberBook 엔티티의 수를 카운팅하는 역할이다.
하지만 유저가 5번 책을 대여한 뒤, 5번의 반납을 한 다음,
다시 대여를 요청하면 5번의 반납 사실이 카운팅되지 않고, 대여의 횟수만이 기록이 되는 에러가 발생.
[원인]
Spring Data JPA에서 제공하는 자동 메서드 성격 차이.
이 자동 메서드는 predefined method인 만큼,
모든 메서드들을 이름에 따라 그 동작을 알고 사용해야하지만 미숙함이 원인이었다.
[해결]
-기존- countByMember(Member member)
MemberBook 테이블에서 전달된 member(memberId)와 연관된 row(가로행)을 카운팅한다.
MemberBook 엔티티 클래스에는 Member member 필드가 있는데
이 필드의 테이블 명은 memberId 라고 설정해두었다.
즉, countByMember(Member member)은 Spring Data JPA에서 사용하는 자동 메서드로써
실제 Spring Data JPA는 자동으로 countByMember(Member member)를 아래의 SQL 쿼리문으로 변경.
SELECT COUNT(*) FROM MemberBook WHERE memberId = ?
-개선- countByMemberAndReturnedAtIsNull(Member member)
기존의 메서드에서 And로 추가적인 조건을 추가.
즉, MemberBook 테이블에서 파라미터로 전달되는 member(memberId)와 일치하는 row(가로행)에서 ReturnedAt 필드가 IsNull 인 row만 카운팅하는 메서드로 수정.
SQL 쿼리로 변경하게 되면
SELECT COUNT(*) FROM MemberBook WHERE memberId = ? AND returnedAt IS NULL;
'마주쳤던 이슈 기록' 카테고리의 다른 글
#8. JUnit - The following parts of the payload were not documented (0) | 2023.05.19 |
---|---|
#7. 로그인 이후 response Header에 JWT 미전달 (0) | 2023.05.18 |
#5 Mapper: Dto -> Entity 변환 시 Null 에러 (0) | 2023.05.09 |
#4. @Value 애너테이션 미인식 에러 (0) | 2023.05.02 |
#3. Spring Security 순환 참조 에러 (0) | 2023.05.01 |