221004 TIL Failed to create query....

Failed to create query for method public abstract

오늘 만난 오류는 Failed to create query for method public abstract이라는 오류를 만났다.

JPA Repository에서 특정 id값의 데이터를 가져오다가 만난 걸로 추정이 되는데 당시에 마주했을 때는 왜 이런 오류가 발생했는지 파악할 수 없었다. 

 

 

에러 메시지도 전부 빨간 글씨여서 잠깐 당황을 했다... 이렇게 에러 메시지를 띄워주면 당황스럽다고요..

파란색으로 어떤 코드가 잘못되었는지 알려주는 에러들은 그나마 추적해나가면서 해결할 수 있는데 위 에러는 불친절하게도 그런 게 없다..

근데 자바도 내가 잘못했으니까 저러겠지.. 

 

심호흡 한번 하고 에러의 원인을 알려주는 Reason부터 찾으려고 했다.

읽다가 눈알이 빠질 뻔했지만 중간쯤에서 겨우 찾을 수 있었다. Reason: Failed to create query for method public abstract

 

오류 메시지만 보면 쿼리를 만들지 못했다고 하는데 쿼리를 만드는 거랑 repository에서 데이터를 찾는 거랑 상관관계가 없다고 생각을 했었다. 그래서 혼자 힘으로는 해결하지 못할 것 같아서 구글링을 해봤다.

 

Failed to create query for method public abstract오류가 발생한 이유는 여러 가지 이유가 있는 것으로 파악을 했다.

우선 Entity의 property의 name을 스네이크 표기법 대신 카멜 표기법을 사용해야 한다.

그 이유는 자바에서는 underscore(_)를 예약 문자로 취급하기 때문에 카멜 케이스를 권장한다고 한다.

 

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-property-expressions

 

Spring Data JPA - Reference Documentation

Example 109. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del

docs.spring.io

하지만 이 경우는 내 오류를 해결할 수 없다. 왜냐하면 나는 자바를 사용하면서 스네이크 표기법을 사용해본 적이 없기 때문이다.

내 Entity는 카멜 케이스란 말이다...

 

또 다른 해결방안을 찾다가 repository 커스텀 메서드와 entity의 property와 비교할 때 불일치하거나 잘못된 이름이 있으면 문제가 발생한다고 하는 글을 봤다. 

내 오류 메시지에도 아래와 같이 Product entity에서 productId라는 걸 못 찾는다고 하는데 딱 이 문제인 것 같았다.

 

내 ProductRepository의 메서드명과 Product Entity를 보니 문제를 확신할 수 있었다.

Optional<Product> findByProductId(Long id);

 

ProductId를 찾는 메서드를 정의하고 Entity에는 ProductId라는 property는 존재하지 않았다.

 

레파지토리의 메서드명이 무슨 상관이 있겠어하고 상품의 아이디로 상품을 찾는다는 의미를 드러내고 싶어서 ProductId라고 정의했지만 jpa의 repository에서는 메서드 명도 일치시켜줘야 한다는 것을 깨달았다.

 

지금은 리액트에서 페이지를 새로고침 시 데이터가 사라지는 문제를 겪고 있는데 이것도 삽질 좀 하면 어떻게든 해결할 수 있지 않을까..?

에러를 마주하면 고통스럽긴 하지만 이렇게 에러를 하나씩 해결해나가면서 하나씩 배워가는 게 정말 많은 느낌이다.