[Project] 2차 프로젝트 - error: 대여중인 도서 반납 기능 에러 해결

김호정's avatar
Oct 25, 2024
[Project] 2차 프로젝트 - error: 대여중인 도서 반납 기능 에러 해결

LendService

// book_Tb -> 대여상태 false, 대여수 -1 // lend_tb -> 반납한 일자 (now), 반납상태 -> true @Transactional public LendResponse.ReturnDTO 직접반납하기(Long userId, LendRequest.ReturnDTO request) { // 1. 대여상태인지 확인 Boolean b = bookRepository.mCheckLendStatus(request.getIsbn13()).orElseThrow(() -> new ExceptionApi404("요청하신 도서가 존재하지 않습니다.")); if (!b) { throw new ExceptionApi404("대여중인 도서가 아닙니다."); } // 2. booktb 대여 상태 바꾸기 int updateCount = bookRepository.mUpdateLendStatusAndCountReturn(request.getIsbn13()); // 업데이트가 성공했는지 확인 (1이 아니면 실패) if (updateCount != 1) { throw new ExceptionApi500("도서 반납 처리 중 문제가 발생했습니다."); } // 3.lend_tb 대여 상태 바꾸기 int returnStatus = lendRepository.mReturnLend(userId, request.getIsbn13()); // 업데이트 성공했는지 확인 (1이 아니면 실패) if (returnStatus != 1) { throw new ExceptionApi500("도서 반납 처리 중 문제가 발생했습니다."); } // 4. 반납정보 return Lend lendPS = lendRepository.mFindLend(userId, request.getIsbn13()); return new LendResponse.ReturnDTO(lendPS); }
 
→ 처음에 구현한 “도서반납하기” 기능의 서비스 레이어 코드.
 
마지막 4. 반납정보 return 부분의 mFindLend 의 쿼리는
 

LendRepository

// 해당 user와 book의 lend 데이터 조회 @Query("select l from Lend l where l.user.id = :userId AND l.book.isbn13 = :isbn13") Lend mFindLend(@Param("userId") Long userId, @Param("isbn13") String isbn13);
 
이렇게 user_id와 isbn13(book의 pk)를 가지고 lend 데이터 조회하는 쿼리다.
 
해당 유저가 여러번 해당 도서를 빌리고 반납했다면 lend_tb에 그 히스토리가 남기때문에 ( → return_status = false, true 로 반납된 도서인지 아닌지 구분하기 때문에 lend_tb에 대여한 도서 내역과 지금 대여중인 도서 내역이 전부다 들어가 있다. )
userId와 isbn13으로 조회하면 하나의 객체가 아니라 List가 출력될텐데
그 부분을 생각하지 못했다.
 
notion image
 
→ 기존에 빌린 내역이 없는 책은 이렇게 성공적으로 반납이 되어서 잘 되는줄 알았다.
 
하지만 기존에 9791190669238 이 도서를 빌린 내역이 있으면
 
notion image
 
💡
{"reason": Query did not return a unique result: 2 results were returned}
 
이렇게 List로 받지 못해서 에러가 터진다.
 
→ 그래서 service 레이어 에서 반납정보를 찾아오는 쿼리를 수정했다.
 

LendRepository

// 가장 최근에 반납한 도서 1개를 select 하거라 @Query(value = "SELECT * FROM lend_tb WHERE user_id = :userId AND book_id = :isbn13 AND return_status = true ORDER BY return_date DESC LIMIT 1", nativeQuery = true) Optional<Lend> findLatestReturnedLendNative(@Param("userId") Long userId, @Param("isbn13") String isbn13);
 
: 대여 내역중에 가장 최근에 반납한 ( = 방금 반납한 그 반납내역 ) 것만 select 하는 쿼리 !
ORDER BY return_date DESC LIMIT 1 를 추가해서
 
return_date를 내림차순으로 정렬해서 그 중 맨 윗단에 있는 1개 ( = 방금 반납한 그 반납내역 )를
지정하도록 했다.
 

LendService

// 5. 반납정보 return Lend lendPS = lendRepository.findLatestReturnedLendNative(userId, request.getIsbn13()) .orElseThrow(() -> new ExceptionApi404("반납된 기록을 찾을 수 없습니다."));
 
방금 만든걸로 바꿔줬다.
 

LendService

// book_Tb -> 대여상태 false, 대여수 -1 // lend_tb -> 반납한 일자 (now), 반납상태 -> true @Transactional public LendResponse.ReturnDTO 직접반납하기(Long userId, LendRequest.ReturnDTO request) { // 1. 대여상태인지 확인 Boolean b = bookRepository.mCheckLendStatus(request.getIsbn13()).orElseThrow(() -> new ExceptionApi404("요청하신 도서가 존재하지 않습니다.")); if (!b) { throw new ExceptionApi404("대여중인 도서가 아닙니다."); } // 2. booktb 대여 상태 바꾸기 int updateCount = bookRepository.mUpdateLendStatusAndCountReturn(request.getIsbn13()); // 업데이트가 성공했는지 확인 (1이 아니면 실패) if (updateCount != 1) { throw new ExceptionApi500("book도서 반납 처리 중 문제가 발생했습니다."); } // 3.lend_tb 대여 상태 바꾸기 int returnStatus = lendRepository.mReturnLend(userId, request.getIsbn13()); // 업데이트 성공했는지 확인 (1이 아니면 실패) if (returnStatus != 1) { throw new ExceptionApi500("lend도서 반납 처리 중 문제가 발생했습니다."); } // 4. 반납 후 예약자가 있는지 확인하여 처리 - TODO: 신민재 boolean hasReservations = reservationRepository.countCurrentReservations(request.getIsbn13()) > 0; if (hasReservations) { // 첫 번째 예약자에게 자동 대여 처리 reservationService.자동대여(request.getIsbn13()); } // 5. 반납정보 return Lend lendPS = lendRepository.findLatestReturnedLendNative(userId, request.getIsbn13()) .orElseThrow(() -> new ExceptionApi404("반납된 기록을 찾을 수 없습니다.")); return new LendResponse.ReturnDTO(lendPS); }
 
⇒ “반납 기능” 서비스 레이어 최종 코드
 
그리고 나서 기존 9791190669238 도서의 대여 내역을 여러개 만들고
이 있는 도서를 다시 빌린 후 반납해야하는 상황에서 반납하기를 요청하면
 
notion image
→ 반납이 잘 된다!
 
Share article

keepgoing