졸업 프로젝트를 하던 도중 발생한 오류이다.
📌 문제 상황
데이터베이스에 샘플 데이터도 삽입해두었고 SpringBoot 어플리케이션도 정상적으로 Run 되는 상황에 API 테스트를 했는데 403오류가 발생했다. 로그를 확인해보니 다음과 같은 오류가 눈에 띄었다!
Expecting a SELECT Query [...], but found org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement [INSERT INTO SolvedElement (element , isSolved , solvedAt ) VALUES (:element , :isSolved , :solvedAt )]
🖍 원인
이 오류는 Hibernate가 SELECT 쿼리를 기대했지만 INSERT 쿼리가 전송되었다는 것을 나타낸다고 함.
'SolvedElement; 테이블에 INSERT 쿼리를 수행하려고 했지만 Hibernate가 SELECT 쿼리를 예상한 상황에서 발생한 것임..
코드를 살펴보니.. ArtworkRepository 인터페이스에서 메서드가 INSERT 쿼리를 실행하도록 정의되어 있는 것이 원인이었다.
@Query("INSERT INTO SolvedElement(element, isSolved, solvedAt) VALUES (:element, :isSolved, :solvedAt)")
void saveSolvedElement(@Param("element") Element element, @Param("isSolved") boolean isSolved, @Param("solvedAt") LocalDateTime solvedAt);
🔨 해결 방법
JpaRepository의 save 메서드를 활용한다! save() 메서드는 새 entity를 추가할뿐만 아니라 업데이트를 위한 용도로 사용된다.
1. 기존 레포지토리 파일에서 쿼리 insert문을 save 메서드로 변경
@Override
<S extends Element> S save(S entity);
2. 서비스 클래스의 메서드 내부에서도 레포지토리명.save 메서드를 호출하도록 변경
solvedElementRepository.save(solvedElement);
이렇게 수정하면 Hibernate가 해당 메서드를 통해 INSERT 쿼리문 없이도 INSERT 쿼리를 실행하게 된다!

+) 3. 새 레포지토리 파일 추가
이 단계는 프로젝트마다 다를 수 있음! 저는 1, 2로 변경을 해도 여전히 오류가 발생했는데 그 이유는 기존 레포지토리 파일의 save 메서드에는 제가 저장하고자 하는 엔티티 타입의 매개변수가 없었기 때문이다.
따라서 해당 객체를 저장하기 위해서는 별도의 리포지토리 인터페이스를 정의하고, 해당 인터페이스를 사용하여 객체를 저장했어야 했다!
@Repository
public interface SolvedElementRepository extends JpaRepository<SolvedElement, Long> {
}
[참고]