Spring Data JPA 의 메소드 네임 쿼리를 사용하기 어려운 복잡한 쿼리의 경우, JPQL 이나 QueryDsl 를 사용한다.
그 중에서 문자열로 쿼리를 날리는 JPQL 을 연습하고 있었다... JPQL 은 날쿼와는 다르게 데이터베이스에 상관 없이 똑같은 SQL 문을 사용한다.
그런데 문제! DTO 로 결과값을 반환하려고 하는데, 결과값이 기대하는 배열의 길이와는 맞지만, 모든 값이 null 이 뜨는 오류가 생겼다.
// n번 이상 별점 n점 이상을 받은 제품
@Query(value =
"SELECT p" +
" FROM Product p" +
" WHERE p.productId IN (SELECT r.product.productId" +
" FROM Review r" +
" WHERE r.rating >= ?1 " +
" GROUP BY r.product " +
" HAVING COUNT(r) >= ?2)"
)
List<ProductDto> findProductByRatingGreaterThanEqual(Integer rating, long howMuch);
위에 보이는 것 처럼 배열은 잘 가져왔지만 값이 null이었다. 200OK 라서 오류 메세지도 제대로 안나오기 때문에 대체 어디가 잘못 되었는지를 알 수가 없었다...
// n번 이상 별점 n점 이상을 받은 제품
@Query(value =
"SELECT p.productId, p.category, p.modelNumber, p.modelName, p.productImage, p.unitCost, p.description" +
" FROM Product p" +
" WHERE p.productId IN (SELECT r.product.productId" +
" FROM Review r" +
" WHERE r.rating >= ?1 " +
" GROUP BY r.product " +
" HAVING COUNT(r) >= ?2)"
)
List<ProductDto> findProductByRatingGreaterThanEqual(Integer rating, long howMuch);
DTO 와의 매핑의 문제? 혹은 순서가 랜덤이라서 그런가 싶어 각 항목의 이름을 제대로 명시해주었다.
하지만... 위의 오류와 똑같이 모든 값이 null 이 나왔다.
// n번 이상 별점 n점 이상을 받은 제품
@Query(value =
"SELECT p.productId as productId, p.category as category, " +
"p.modelNumber as modelNumber, p.modelName as modelName, " +
"p.productImage as productImage, p.unitCost as unitCost, " +
"p.description as description" +
" FROM Product p" +
" WHERE p.productId IN (SELECT r.product.productId" +
" FROM Review r" +
" WHERE r.rating >= ?1 " +
" GROUP BY r.product " +
" HAVING COUNT(r) >= ?2)"
)
List<ProductDto> findProductByRatingGreaterThanEqual(Integer rating, long howMuch);
문제는
as
였다.
as 를 써주지 않아서 엔티티와 제대로 매핑이 안된 것이었다! 가져오기는 했는데 어떤 곳에 매핑해야 할지 몰라서 null 을 써준 것 같다...
GET http://localhost:8080/product?rating=3&howMuch=2
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 29 Feb 2024 11:31:43 GMT
Keep-Alive: timeout=20
Connection: keep-alive
[
{
"description": "this is product 1",
"unitCost": 5000,
"modelNumber": "123A",
"modelName": "product1",
"category": [
{
"categoryId": 1,
"categoryName": "Book"
}
],
"productId": 1,
"productImage": "product1.png"
},
{
"description": "this is product 3",
"unitCost": 5000,
"modelNumber": "123A",
"modelName": "product3",
"category": [
{
"categoryId": 1,
"categoryName": "Book"
}
],
"productId": 3,
"productImage": "product3.png"
}
]
Response file saved.
> 2024-02-29T203143.200.json
Response code: 200; Time: 979ms (979 ms); Content length: 385 bytes (385 B)
드디어 원하는 결과가 나왔다!!!!!!
as(컬럼명)
을 써야한다.long 타입
의 숫자와 비교한다.