Programming/Spring

[QueryDSL] NoSuchMethodError Trouble Shooting

osean 2023. 2. 22. 01:17

๋“ค์–ด๊ฐ€๊ธฐ ์•ž์„œ

ํ˜„์žฌ QueryDSL 5.0.0 ๋ฒ„์ „์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ”„๋กœ์ ํŠธ ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ๋ณต์žกํ•œ ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ๊ฐ€์ง€๋Š” ํ…Œ์ด๋ธ”์„ JPA Mapping ์„ ์‚ฌ์šฉํ•ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•  ๊ฒฝ์šฐ ๋„ˆ๋ฌด ๋งŽ์€ ์ฟผ๋ฆฌ๋ฅผ ์š”์ฒญํ•˜๊ฒŒ ๋˜์–ด ๋ถˆํ•„์š”ํ•œ ์ž์›์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด @Query ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด ๋ ˆํผ์ง€ํ† ๋ฆฌ์— ์กฐํšŒ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ ค ํ–ˆ์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์œ ๋กœ ๋ฐ˜๋ คํ–ˆ๋‹ค.

  • ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์„ ํ•œ ๋ฒˆ์— ์กฐํšŒํ•ด ํ•˜๋‚˜์˜ ๋„๋ฉ”์ธ ํด๋ž˜์Šค๋กœ ์žฌ๊ตฌ์„ฑํ•ด์•ผ ํ•˜๋ฉฐ, ์—ฌ๋Ÿฌ ์กฐ๊ฑด์˜ ๊ฒฐ๊ณผ๋ฅผ GroupBy ํ•˜์—ฌ ์ž„๋ฒ ๋””๋“œ ํด๋ž˜์Šค์˜ ํ•„๋“œ์— ํ• ๋‹นํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ @Query ์• ๋…ธํ…Œ์ด์…˜์€ ๊ตฌํ˜„์ด ์–ด๋ ค์šธ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.
  • ํŠน์ • ์—”ํ‹ฐํ‹ฐ์˜ ๋ ˆํผ์ง€ํ† ๋ฆฌ์— @Query ๋ฅผ ์‚ฌ์šฉํ•ด ์กฐํšŒ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ํ•ด๋‹น ๋ ˆํผ์ง€ํ† ๋ฆฌ์— ๋ถˆํ•„์š”ํ•œ ์ฑ…์ž„์„ ๋ถ€์—ฌํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

์ด๊ฐ™์€ ์ด์œ ๋กœ QueryDSL ์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฒฐ๊ณผ ์ง‘ํ•ฉ ํ•จ์ˆ˜๋ฅผ ์ ๊ทน ํ™œ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์„ ์กฐํšŒํ•˜๊ณ  ๊ฐ ์กฐ๊ฑด์— ๋งž๋Š” ๊ฒฐ๊ณผ๋ฅผ ํ•˜๋‚˜์˜ ๋„๋ฉ”์ธ ํด๋ž˜์Šค์— ๋งตํ•‘ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

@QueryProjection

๋งตํ•‘ํ•  ๋„๋ฉ”์ธ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์— @QueryProjection ์ ์šฉํ•ด ๋„๋ฉ”์ธ ํด๋ž˜์Šค์˜ QClass ์ƒ์„ฑ์ž ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. Projections.bean() / Projections.fields() ์™€ ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ, ์–ด๋–ค ์ด์œ ์—์„œ์ธ์ง€ ๋งตํ•‘์ด ๋˜์ง€ ์•Š์•˜๋‹ค. (java.lang.IllegalArgumentException: argument type mismatch ๋ฐœ์ƒ)

// ์ œํ’ˆ ๋„๋ฉ”์ธ ํด๋ž˜์Šค
data class Product @QueryProjection constructor(
  val categoryId: String,
  val categoryName: String,
  val productId: String,
  val name: String,
  val price: Int,
  val keywords: List<Keyword>
)

// ์ œํ’ˆ ํ‚ค์›Œ๋“œ ๋„๋ฉ”์ธ ํด๋ž˜์Šค
data class Keyword @QueryProjection constructor(
  val keywordId: String,
  val keyword: String,
  val productId: String
)

transform(...)

PersistenceAdapter ์—์„œ ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•˜๋Š” Port ์˜ ํ•จ์ˆ˜์— QueryFactory ๋ฅผ ์‚ฌ์šฉํ•ด ๋„๋ฉ”์ธ ํด๋ž˜์Šค๋กœ ๋ฐ”๋กœ ๋ฆฌํ„ดํ•ด์ฃผ๋„๋ก ํ•œ๋‹ค.
๋งŒ๋“ค๋ฉด์„œ ๋ฐฐ์šฐ๋Š” ํด๋ฆฐ ์•„ํ‚คํ…์ณ ์—์„œ๋Š” DomainMapper ๋ฅผ ์ด์šฉํ•ด ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์˜ ์กฐํšŒ ๊ฒฐ๊ณผ๋ฅผ ๋„๋ฉ”์ธ ํด๋ž˜์Šค์— ๋งตํ•‘ํ•ด์ฃผ๋„๋ก ํ•˜๋Š”๋ฐ, ํ•ด๋‹น ๊ณผ์ •์—์„œ ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๋ถˆํ•„์š”ํ•œ ์กฐํšŒ ์ฟผ๋ฆฌ ์š”์ฒญ ๋ฐ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฒˆ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์—์„œ๋Š” ์ œ์™ธํ•˜๋„๋ก ํ•œ๋‹ค.

// QClass static import
@PersistenceAdapter
class ProductPersistenceAdapter(
    private val queryFactory: JpaQueryFactory
) : GetProductPort {

    override fun getProducts(categoryId: String): List<Product> {
        return queryFactory
          .from(eCategory)
          .join(eProduct).on(eProduct.categoryId.eq(eCategory.id))
          .leftJoin(eKeyword).on(eKeyword.productId.eq(eProduct.id))
          .where(eCategory.id.eq(categoryId))
          .transform(
            groupBy(eCategory.id)
              .list(
                QProduct(
                  eCategory.id,
                  eCategory.name,
                  eProduct.id,
                  eProduct.name,
                  eProduct.price,
                  list(
                    QKeyword(
                      eKeyword.id,
                      eKeyword.keyword,
                      eKeyword.productId
                    )
                  )
                )
              )
          )
    }
}

NoSuchMethodError

์œ„์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋‹ˆ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

Caused by: java.lang.NoSuchMethodError: 'java.lang.Object org.hibernate.ScrollableResults.get(int)'

ํ•ด๋‹น ์—๋Ÿฌ๋ฅผ ๋””๋ฒ„๊น… ํ•ด๋ณด๋‹ˆ ์กฐํšŒํ•œ ๋ฐ์ดํ„ฐ๋“ค์„ ๋„๋ฉ”์ธ ํด๋ž˜์Šค์˜ QClass ์ƒ์„ฑ์ž์˜ ์•„๊ทœ๋จผํŠธ๋กœ ์„ค์ •ํ•˜๋Š” ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์˜€๊ณ , ๋‹ค๋ฅธ ํ•„๋“œ๋“ค์€ ๊ดœ์ฐฎ์•˜๋Š”๋ฐ Left Join ์œผ๋กœ ์กฐํšŒํ•œ Keyword ๋ฐ์ดํ„ฐ๋ฅผ List ๋กœ ๋งตํ•‘ํ•˜๋Š” ์ค‘์— ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํ™•์ธ๋๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๊ตฌ๊ธ€๋ง ํ•ด๋ณธ ๊ฒฐ๊ณผ, ๋‹ค์Œ์˜ ์ด์Šˆ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

'Programming > Spring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Spring Security] @AuthenticationPrincipal Test Trouble Shooting  (0) 2023.04.08
Criteria API  (0) 2023.01.28
Spring Bean / IoC Container / DI  (1) 2023.01.21
JPA / Persistence Context / Transactional  (2) 2023.01.14
Spring | Spring Framework ?  (0) 2020.08.02