본문 바로가기
Side Projects/프로젝트 사이

6. 오류 해결 스토리 - Update/delete queries cannot be typed

by devraphy 2022. 7. 30.

0. 문제 설명

a) JPQL을 이용한 Update 쿼리 작성

- 회원 정보를 수정하기 위해서 다음과 같은 쿼리문을 작성했다.

 

public int updateById(Long id, String name, String email, String password) {
    return em.createQuery("update Member as m " +
            "set m.name = :name, m.email = :email, m.password = :password where m.id = :id", Member.class)
            .setParameter("id", id)
            .setParameter("name", name)
            .setParameter("email", email)
            .setParameter("password", password)
            .executeUpdate();
}

 

- 그리고 테스트 과정에서 다음과 같은 오류가 발생했다.

 

org.springframework.dao.InvalidDataAccessApiUsageException: Update/delete queries cannot be typed; nested exception is java.lang.IllegalArgumentException: Update/delete queries cannot be typed

 

- 오류 메시지를 해석해보면 update 또는 delete 쿼리를 작성할 수 없다는 의미다.

- 또 하나의 신박한 오류를 발견했다. 

 

 

1. 문제 해결

a) 생각보다 간단한 해결 방법 

- 해결 방법은 간단하다.

- createQuery() 메서드의 매개변수로 마지막에 들어가는 class를 제거해주면 된다. 다음 코드처럼 말이다. 

 

public int updateById(Long id, String name, String email, String password) {
    return em.createQuery("update Member as m " +
            "set m.name = :name, m.email = :email, m.password = :password where m.id = :id")
            .setParameter("id", id)
            .setParameter("name", name)
            .setParameter("email", email)
            .setParameter("password", password)
            .executeUpdate();
}

 

 

b) 왜? Why?

- JPQL을 작성하는 방법으로 EntityManager의 createQuery() 메서드를 사용한다.

- createQuery() 메서드의 매개변수로 들어가는 Query는 사실 2가지 종류로 구분된다. 

    → Typed Query: 조회 대상과 반환형이 Entity인 쿼리 

    → Query: 조회 대상과 반환형이 Entity가 아닌, 기본형 또는 Wrapper 클래스인 쿼리 

 

- 다음 예시 코드를 살펴보자. 

 

// 1. TypedQuery
// => 조회 대상이 엔티티(= Member)이고, 반환 값이 엔티티(= Member)다. 
TypedQuery<Member> query = em.createQuery("SELECT m FROM Member m", Member.class);

// 2. 일반 Query
// => 조회대상과 반환 값이 Entity가 아닌, String이나 Integer 이다.
Query query = em.createQuery("SELECT m.username, m.age FROM Member m");

 

- 이 기본 개념을 기반으로 Update 쿼리를 이해해보자.

- Update 쿼리는 엔티티를 조회하지도, 반환하지도 않는다.

- 즉, 조회 대상과 반환 값의 형태가 불분명하므로 일반 Query를 작성하는 것에 해당한다. 

- 그러므로 클래즈 변수(= .class)를 명시하지 않는다.

 

 

c) 기본! 기본! 또 기본!

- 내가 직접 정리를 해놨음에도 불구하고 이번에도 기본 개념을 간과하여 발생한 문제였다.

 

https://devraphy.tistory.com/566

 

23. JPQL - 기본 기능(파라미터 바인딩, 결과 조회, 쿼리의 종류)

0. 개요 - 이전 포스팅에서 JPQL에 대해서 전반적으로 알아보았다. - 이번 포스팅에서는 JPQL의 기본 문법과 기능에 대해서 알아보자. 1. 기본 규칙 - JPQL은 다음과 같은 기본 규칙을 준수해야 한다.

devraphy.tistory.com

 

- 모든 기본 개념을 항상 머릿속에 암기하고 있다면 정말 좋겠지만,

- 이런 경험들이 쌓여서 필요할 때마다 꺼내 쓸 수 있도록 더 익숙해져야겠다. 

- 즉, 많이 만들어봐야 한다. 

댓글