• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

loanBook 메소드 만들 때 유저정보 가져오는 코드에서 오류가 납니다

23.02.26 20:51 작성 조회수 285

1

 예외 처리 부분이니까 주석 처리하면 실행될까 했는데 아래와 같은 에러메시지가 나옵니다.

 

혹시 몰라 전체 코드를 깃헙에 업로드해놓겠습니다!

https://github.com/you-eun-hye/library-app-Inflearn

답변 1

답변을 작성해보세요.

1

안녕하세요! 은혜님!! 질문 올려주셔서 감사드립니다!! 😊

 

내용을 잘 정리해주셔서 에러를 금방 찾을 수 있었는데요! 어떻게 제가 에러를 찾았는지 천천히 말씀드려보겠습니다!

 

우선 가장 먼저 보내주신 에러 내용 (빨간색 글씨)를 읽었습니다!

에러 내용의 경우 가장 윗줄에 있는 문구가 1차 원인이고, 뒷줄로 갈 수록 근본 원인에 가까워진다는 특징이 있습니다.
지금 경우도 살펴보면, 1차 원인은 Error creating bean with name 'bookService' defiend in file [...] 이라고 나오고 있죠! 이 의미는 bookService 라는 빈을 만드는데 실패했다는 의미입니다! bookService 를 못만들어서 서버가 시작되지 않은거죠.

그러면 bookService 는 왜 실패했을까요?! 그 다음 줄에 나와 있습니다. Error creating bean with name 'bookLoanHistoryRepository' defined in file [...] 이라고 되어 있는데요! bookLaonHistoryRepository를 빈으로 만드는데 실패한겁니다!

이런식으로 에러를 정리해보면 다음과 같은 사실을 알 수 있습니다.

  • 현상

    • 서버 시작 실패

  • 서버 시작이 실패한 원인

    • BookService 빈 생성 실패

  • BookService 빈 생성이 실패한 원인

    • BookLoanHistoryRepository 빈 생성 실패

  • BookLoanHistoryRepository 빈 생성이 실패한 원인

    • findByName(java.lang.String) 함수에 대한 쿼리 생성 실패

  • findByName(java.lang.String) 함수에 대한 쿼리 생성이 실패한 원인

    • UserLoanHisotry 객체에 name이라는 필드가 없기 때문!!!

 

실제로 올려주신 github의 다음 두 코드를 살펴보면

UserLoanHisotryRepository에서는 findByName 을 쓰시고 있고요! UserLoanHistory에서는 name 대신 bookname이 있습니다!

findByXXX 에서 XXX는 해당 도메인 객체 필드에 있는 이름을 사용해야 하기 때문에

  • 기존에 있던 findByName은 BookRepository로 옮겨주시거나

  • findByName 대신 findByBookName을 사용하시면 되지 않을까

싶습니다 ㅎㅎㅎ

 

혹시나 어려운 부분이나 잘 안되는 부분 있으시면 또 편하게 질문 남겨주세요!

감사합니다~~ 오늘도 행복한 하루 되세요!!! 🙏🙏

 

유은혜님의 프로필

유은혜

질문자

2023.02.27

빠르게 답글 달아주셔서 감사합니다!

답글 달아주신 거랑 강의자료 중 완성코드 자료를 참고해서 수정을 해봤습니다!

 

  • 기존에 UserLoanHistoryRepository에 있던 findByName은 삭제했습니다.

  • BookRepository에 findByNameOptional을 붙여줬습니다.

  • UserServiceV2에 deleteUser에 코드를 .orElseThrow를 사용하여 변경해줬습니다.

 

위 작업을 거치니 빨간 줄은 모두 사라졌습니다만 에러는 아래와 같이 발생합니다.

image

감사하게도 에러를 찾는 방법에 대해서도 작성해주셔서 확인해보니

UserLoanHistory 객체에 existByBookName 필드가 없어서 생기는 에러로 보입니다.

 

근데 existByBookName은 JPA쿼리 활용을 위해 findAllByNamAndAge 처럼 사용했던 것으로 기억하고 필드를 만들어준 기억은 없는데 왜 이런 에러가 생기는 걸까요..😥

 

이번에도 깃헙에 새로 올려놓았습니다!

https://github.com/you-eun-hye/library-app-Inflearn

안녕하세요 은혜님~~~ 크으~~~ 정말 나이스입니다!!! 👍👍 (에러를 해결하고 다른 에러의 의미도 완전히 파악하셨군요~~~!!!)

이번 경우의 문제를 설명드려 보자면, 바로 existByBookName 자체를 필드로 인식해서 문제입니다~

그 이유는 exists 가 아니라 exist 가 들어가서 그렇습니다!!!! (끝에 s 가 빠져 있어요!)

Spring Data JPA에서는 exists 가 예약어로 사용되거든요! exist 대신 exists 를 잘 넣어주시면 정상 동작할 것 같습니다!

 

이게 바로 Spring Data JPA의 단점이고 (😭) 이를 보완하기 위해 Querydsl을 사용하게 됩니다. (관련 내용은 <실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 - 37강. Querydsl 도입하기>에서 다루고 있습니다)

감사합니다!!!! 🙏🙏

유은혜님의 프로필

유은혜

질문자

2023.02.27

흐어어어어 되네요ㅠㅜㅠㅜㅠㅜ s 안쓴 걸 못찾아서 이 고생을,,,ㅠㅠㅠ

Querydsl 이라는 걸 덕분에 알게 됐네요!

이거 먼저 완강하고 코틀린도 들어보겠습니다! 감사합니다 :)