반응형
개요
개인 프로젝트에서 JpaRepository에 delete 쿼리를 작성하면서 생긴 문제점을 이 글에 정리한다.
문제점
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class LikedVoucher extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "voucher_id")
private Voucher voucher;
@Builder
public LikedVoucher(Voucher voucher) {
this.voucher = voucher;
}
public void setMember(Member member) {
this.member = member;
}
}
위의 LikedVoucher entity는 Member, Voucher 와 연관관계를 맺고 있으며,
@Query("delete from LikedVoucher lv " +
"where lv.voucher.id = :voucherId and lv.member.username = :username")
void deleteByUsernameAndVoucherId(String username, Long voucherId);
위의 코드는 Member 의 username과 Voucher의 id에 해당하는 LikedVoucher를 삭제하는 쿼리이다. 이 상태로 위의 메소드를 테스트하면 아래와 같이 오류가 발생한다.
jakarta.servlet.ServletException: Request processing failed: org.springframework.dao.InvalidDataAccessApiUsageException: Expecting a SELECT query : `delete from LikedVoucher lv where lv.voucher.id = :voucherId and lv.member.username = :username`
SELECT 쿼리를 예상했지만, @Query 애노테이션 안에 작성된 jpql은 DELETE이기 때문에 발생하는 오류이다.
해결법
@Query는 기본적으로 조회하는 쿼리만 인식할 수 있다. 그래서 위와 같이 변경이 일어나는 작성하는 경우에는 동작하지 않는다. 변경이 일어나는 쿼리를 작성하고 싶다면 아래와 같이 @Modifying 애노테이션을 하나 추가해야 한다.
@Modifying // 추가
@Query("delete from LikedVoucher lv " +
"where lv.voucher.id = :voucherId and lv.member.username = :username")
void deleteByUsernameAndVoucherId(String username, Long voucherId);
@Modifying의 소스코드에 있는 문서를 확인해보면, 아래와 같은 문구를 확인할 수 있다.
Indicates a query method should be considered as modifying query as that changes the way it needs to be executed. This annotation is only considered if used on query methods defined through a Query annotation.
대략 "@Modifying이 적용된 쿼리 메소드를 수정 쿼리로 인식될 수 있도록 만들어주는 애노테이션이며, @Query 애노테이션이 적용된 메소드에만 적용된다" 라는 내용을 담고 있다.
즉, @Query 애노테이션을 사용해 메소드에 수정 쿼리를 적용하고 싶다면, 꼭 @Modifying 애노테이션을 추가해야 한다.
반응형
'JPA' 카테고리의 다른 글
[JPA] 임베디드 타입으로 엔티티 개선하기 (0) | 2024.07.19 |
---|---|
[Spring / JPA] Soft Delete를 JPA에서 적용하는 방법 (0) | 2024.05.21 |
[JPA] JPA Auditing (0) | 2023.12.24 |
[JPA] 지연 로딩과 즉시 로딩 (0) | 2023.12.24 |
[JPA] JPA 연관 관계 정리 (0) | 2023.12.24 |