해결된 질문
작성
·
157
·
수정됨
0
김영한님 "자바 ORM 표준 JPA 프로그래밍 - 기본편" 마지막 섹션 내용을 공부하다 에러를 못 고치고 질문 올립니다.
하이버네이트 버전은 6.2.9.FInal이고 부트버전은 3.2.3입니다
@Entity
@Setter
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Product {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
private int stockAmount;
public Product(String name, int price, int stockAmount) {
this.name = name;
this.price = price;
this.stockAmount = stockAmount;
}
}
Product의 price가 double 타입이면 에러가 안 나는데 int면 아래 jpql실행시 에러가 납니다.
@Test
void 벌크연산106p(){
Product p1 = new Product("새우깡", 1000, 5);
Product p2 = new Product("양파깡", 2000, 5);
Product p3 = new Product("고래밥", 5000, 15);
em.persist(p1);
em.persist(p2);
em.persist(p3);
String jpql = "update Product p " +
" set p.price = p.price*1.1 " +
" where p.stockAmount<:stockAmount";
int resultCount = em.createQuery(jpql)
.setParameter("stockAmount", 10)
.executeUpdate();
System.out.println(resultCount + "개 상품 가격 수정");
}
에러 메세지는 다음과 같습니다.
java.lang.IllegalArgumentException: org.hibernate.query.SemanticException: The assignment expression type [java.lang.Float] did not match the assignment path type [java.lang.Integer] for the path [p.price] [update Product p set p.price = p.price*1.1 where p.stockAmount<:stockAmount]
jpql내에 p.price*1.1을 정수로 형변환해서 할당하면 될 것같아, (int)(p.price*1.1)로 바꿔도 에러나네요
답변 1
1
안녕하세요, 인프런 AI 인턴입니다.
spacenyi님, JPA에서의 벌크 연산시 발생하는 타입 불일치 문제에 대해 질문 주셨군요.
에러 메시지를 보면 p.price
필드의 타입이 java.lang.Integer
인데 반해, p.price*1.1
연산의 결과는 java.lang.Float
로 나오기 때문에 타입이 일치하지 않아 에러가 발생하는 것을 알 수 있습니다.
JPQL에서는 자바와 같이 명시적인 타입 캐스팅을 지원하지 않으므로, 곱셈 연산 결과를 정수로 변환하기 위해서는 CAST
함수나 데이터베이스에 맞는 별도의 함수를 사용해야 합니다. 예를 들어, HQL에서는 CAST
표현을 사용하여 필드 값을 다른 값으로 캐스팅 할 수 있습니다.
여기서는 p.price
에 1.1을 곱한 후 다시 정수 타입으로 변환해야 하므로 다음과 같이 쿼리를 수정하시면 될 것 같습니다:
String jpql = "update Product p " +
" set p.price = CAST(p.price * 1.1 AS int) " +
" where p.stockAmount < :stockAmount";
이렇게 수정하면 p.price
필드에 실수 연산 결과가 아닌 정수 결과가 저장되고, 따라서 타입 불일치 문제를 해결할 수 있습니다. 그러나 정확한 함수의 사용법은 사용하시는 데이터베이스에 따라 달라질 수 있으므로, 해당 DBMS의 문서를 참조하시는 것이 좋습니다.
도움이 되었기를 바랍니다.
jpql 내에서 형변환하는 CAST를 쓸 줄 몰라 price를 double형으로 해야 하나 했는데,
답변 대단히 감사합니다.