QueryDSL로 통계 쿼리 작성시 주의점

Dierslair·2022년 10월 14일
2

jpa

목록 보기
4/4

통계를 위해 쿼리를 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.priceLong타입으로 인식하게 할 수 있어 ClassCastException이 발생하지 않는다.

profile
Java/Kotlin Backend Developer

0개의 댓글