본문 바로가기

📝 ErrorNote

[SpringBoot] java.lang.IllegalArgumentException: Modifying queries can only use void or int/Integer as return type! Offending method : @Modifying 리턴타입 확인하기

에러 내용

 

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Modifying queries can only use void or int/Integer as return type! Offending method: public abstract cohttp://m.cos.photogramstart.domain.comment.Comment cohttp://m.cos.photogramstart.domain.comment.CommentRepository.mSave(java.lang.String,int,int); nested exception is java.lang.IllegalArgumentException: Modifying queries can only use void or int/Integer as return type! Offending method: public abstract cohttp://m.cos.photogramstart.domain.comment.Comment cohttp://m.cos.photogramstart.domain.comment.CommentRepository.mSave(java.lang.String,int,int)] with root cause

 

에러 내용

Modifying queries can only use void or int/Integer as return type! 

 

즉, @Modifying 를 붙이면 리턴타입이 int/ integer 타입만 가능하다는 말! 

 

 

 

 

원인 

 @Modifying 은 변경된 엔티티의 수를 반환하거나 void 로 아무것도 반환하지 않는다. 

public interface CommentRepository extends JpaRepository<Comment, Integer> {

    @Modifying // 오류! 
    @Query(value = "INSERT INTO comment(content, imageId, userId, createDate) VALUES (:content, :imageId, :userId, now())", nativeQuery = true)
    Comment mSave(String content, int imageId, int userId);  // 오류! 
}

 

 

해결방법 

반환 타입을 Comment 에서 void 혹은 int 를 리턴하게 해주면 간단하게 해결된다.

 

하지만 나의 경우는 조금 다르다. 

 

나의 경우는 JPARepository 가 제공하는 save 메서드를 사용하여 문제를 해결해야한다. 

 

단순하게 리턴타입을 int/void 로 바꿀 수 없는 이유는 다음과 같다. 

 

사용자가 댓글을 작성하고 댓글을 DB에 저장한 뒤에 변경된 엔티티의 수를 반환받게된다면, 

해당 댓글의 PK를 받아올 수 없다. 

 

PK 를 받아와야지 댓글을 삭제할 때 해당 댓글의 PK 로 내용을 가져올 수 있는데 이게 불가능해진다는 말이다.

@Transactional
public Comment writeComment(String content, int imageId, int userId) {

    // Tip (객체를 만들 때 id 값만 담아서 insert 가 가능함)
    // 대신 return 시에 image 객체와 user 객체는 id 값만 가지고 있는 빈 객체를 리턴받는다.
    Image image = new Image();
    image.setId(imageId);

    User userEntity = userRepository.findById(userId).orElseThrow(() -> {
        throw new CustomApiException("유저 아이디를 찾을 수 없습니다. ");
    });

    Comment comment = new Comment();
    comment.setContent(content);
    comment.setUser(userEntity);
    comment.setImage(image);

    return commentRepository.save(comment);
}

 

따라서 엔티티 객체를 그대로 돌려받는 Spring Data JPA 가 제공하는 save 메서드를 사용했다.