통계를 위해 쿼리를 QueryDSL로 작성하다가 ClassCastException
이 발생하였다.
대략적인 쿼리는 다음과 같다.
select
sum(item.price) as purchase_price,
purchase.*
from
tbl_purchase purchase
left join
tbl_item item -- one to many
on
item.purchase_id = purchase.id
group by
purchase.id
이 쿼리를 QueryDSL로 작성하는 경우,
val item = QItem("item")
val purchase = QPurchase("purchase")
// Item.price 프로퍼티가 Integer로 선언되어 있음
val itemPrice = item.price.sum() // JPQLQuery<Integer>
this.jpaQueryFactory
select(
purchase,
itemPrice,
)
.from(purchase)
.leftJoin(purchase.items. item)
.groupBy(purchase)
.fetch()
.map { tuple ->
val p = tuple.get(purchase) ?: error("never happen")
tuple.get(itemPrice) // ClassCastException
?.let { p.purchasePrice = it.toInt() }
p
}
통계함수 sum
은 QueryDSL에서 Long
타입으로 반환하기 JPQLQuery<Integer>
로 가져오면 오류가 발생한다.
Item.price
프로퍼티 자체가 Integer
타입이기 때문에 변경이 불가능한가... 싶었지만 다행히 QueryDSL에서 제공하는 메서드가 있다.
val itemPrice = item.price.longValue().sum()
쿼리 결과는 그대로이지만, QueryDSL에서 Item.price
를 Long
타입으로 인식하게 할 수 있어 ClassCastException
이 발생하지 않는다.