Hibernate-reactive: MS SQL Server ๋ฐ Hibernate Reactive 1.0.0.CR9์—์„œ ๊ฒฐ๊ณผ๋ฅผ ์ œํ•œํ•  ๋•Œ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋Œ€์ฒด ์˜ค๋ฅ˜ ๋ฐœ์ƒ

์— ๋งŒ๋“  2021๋…„ 08์›” 05์ผ  ยท  13์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: hibernate/hibernate-reactive

์•ˆ๋…•ํ•˜์„ธ์š”, ํŽ˜์ด์ง• ๋˜๋Š” ๋ฒ”์œ„๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ 1.0.0.CR9์—์„œ MS SQL ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค(SQL ์˜ˆ์™ธ, message=''?' ๊ทผ์ฒ˜์˜ ์ž˜๋ชป๋œ ๊ตฌ๋ฌธ.'). ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ Select ์ ˆ์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์Šคํƒ: Quarkus 2.1.0.Final / Panache Reactive / Mutiny 4.1.2 / Hibernate Reactive 1.0.0.CR9 / Hibernate Core 5.5.5.Final

๋‚ด ๋‚˜๋จธ์ง€ ๋ฆฌ์†Œ์Šค์—์„œ ๋‹ค์Œ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
[PanacheRepository].find("firstName LIKE ?1").page(Page.of(25)).list();

Hibernate์—์„œ SQL ๋กœ๊ทธ์˜จ์œผ๋กœ ์ƒ์„ฑ๋œ SQL์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Hibernate:
    select
        top(?) request0_.id as id1_1_,
        request0_.caseId as caseid2_1_,
        request0_.caseNumber as casenumb3_1_,
        request0_.expires as expires4_1_,
        request0_.addressLine1 as addressl5_1_,
        request0_.addressLine2 as addressl6_1_,
        request0_.agency as agency7_1_,
        request0_.city as city8_1_,
        request0_.email as email9_1_,
        request0_.firstName as firstna10_1_,
        request0_.lastName as lastnam11_1_,
        request0_.phone as phone12_1_,
        request0_.relationship as relatio13_1_,
        request0_.state as state14_1_,
        request0_.zipcode as zipcode15_1_,
        request0_.submitted as submitt16_1_
    from
        Request request0_
    where
        request0_.firstName like <strong i="11">@P1</strong>

where ์ ˆ์˜ ์˜ฌ๋ฐ”๋ฅธ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋Œ€์ฒด์— ์œ ์˜ํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๋Ÿฌ๋‚˜ select ์ ˆ์˜ "top(?)"์— ๋Œ€ํ•œ ๋Œ€์ฒด๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
ํŽ˜์ด์ง•์„ ์ œ๊ฑฐํ•˜๊ณ  ๋‹ค์‹œ ์‹คํ–‰ํ•˜๋ฉด ์ฟผ๋ฆฌ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

HQL ๋ฐ SQL์„ ๋ณด์—ฌ์ฃผ๋Š” ์•„๋ž˜ ํ‘œ์‹œ๋œ ์ถ”์  ๋กœ๊น…. Panache๊ฐ€ ์ฟผ๋ฆฌ์— setMaxResults() ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ถ”์ธกํ•ฉ๋‹ˆ๋‹ค. Quarkus ๋˜๋Š” Mutiny์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๋ฌธ์ œ๋ฅผ ์—ด๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. ๋ฏธ๋ฆฌ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

2021-08-05 12:55:57,342 DEBUG [org.hib.hql.int.ast.QueryTranslatorImpl] (vert.x-eventloop-thread-1) HQL: FROM myproject.entities.Request WHERE requestor.firstName LIKE ?1
2021-08-05 12:55:57,342 DEBUG [org.hib.hql.int.ast.QueryTranslatorImpl] (vert.x-eventloop-thread-1) SQL: select request0_.id as id1_1_, request0_.caseId as caseid2_1_, request0_.caseNumber as casenumb3_1_, request0_.expires as expires4_1_, request0_.addressLine1 as addressl5_1_, request0_.addressLine2 as addressl6_1_, request0_.agency as agency7_1_, request0_.city as city8_1_, request0_.email as email9_1_, request0_.firstName as firstna10_1_, request0_.lastName as lastnam11_1_, request0_.phone as phone12_1_, request0_.relationship as relatio13_1_, request0_.state as state14_1_, request0_.zipcode as zipcode15_1_, request0_.submitted as submitt16_1_ from Request request0_ where request0_.firstName like ?
2021-08-05 12:55:57,342 DEBUG [org.hib.hql.int.ast.ErrorTracker] (vert.x-eventloop-thread-1) throwQueryException() : no errors
2021-08-05 12:55:57,342 TRACE [org.hib.rea.ses.imp.ReactiveHQLQueryPlan] (vert.x-eventloop-thread-1) Find: FROM myproject.entities.Request WHERE requestor.firstName LIKE ?1
2021-08-05 12:55:57,344 TRACE [org.hib.eng.spi.QueryParameters] (vert.x-eventloop-thread-1) Named parameters: {1=%j%}
2021-08-05 12:55:57,345 TRACE [org.hib.typ.des.sql.BasicBinder] (vert.x-eventloop-thread-1) binding parameter [2] as [VARCHAR] - [%j%]
2021-08-05 12:55:57,345 TRACE [org.hib.loa.Loader] (vert.x-eventloop-thread-1) Bound [3] parameters total
2021-08-05 12:55:57,355 DEBUG [org.hib.SQL] (vert.x-eventloop-thread-1)
    select
        top(?) request0_.id as id1_1_,
        request0_.caseId as caseid2_1_,
        request0_.caseNumber as casenumb3_1_,
        request0_.expires as expires4_1_,
        request0_.addressLine1 as addressl5_1_,
        request0_.addressLine2 as addressl6_1_,
        request0_.agency as agency7_1_,
        request0_.city as city8_1_,
        request0_.email as email9_1_,
        request0_.firstName as firstna10_1_,
        request0_.lastName as lastnam11_1_,
        request0_.phone as phone12_1_,
        request0_.relationship as relatio13_1_,
        request0_.state as state14_1_,
        request0_.zipcode as zipcode15_1_,
        request0_.submitted as submitt16_1_
    from
        Request request0_
    where
        request0_.firstName like <strong i="18">@P1</strong>
2021-08-05 12:55:57,358 ERROR [org.hib.rea.errors] (vert.x-eventloop-thread-1) HR000057: Failed to execute statement [$1select request0_.id as id1_1_, request0_.caseId as caseid2_1_, request0_.caseNumber as casenumb3_1_, request0_.expires as expires4_1_, request0_.addressLine1 as addressl5_1_, request0_.addressLine2 as addressl6_1_, request0_.agency as agency7_1_, request0_.city as city8_1_, request0_.email as email9_1_, request0_.firstName as firstna10_1_, request0_.lastName as lastnam11_1_, request0_.phone as phone12_1_, request0_.relationship as relatio13_1_, request0_.state as state14_1_, request0_.zipcode as zipcode15_1_, request0_.submitted as submitt16_1_ from Request request0_ where request0_.firstName like @P1]: $2could not execute query: java.util.concurrent.CompletionException: io.vertx.mssqlclient.MSSQLException: {number=102, state=1, severity=15, message='Incorrect syntax near '?'.', serverName='aa3ae4a0fd3c', lineNumber=1, additional=[io.vertx.mssqlclient.MSSQLException: {number=8180, state=1, severity=16, message='Statement(s) could not be prepared.', serverName='aa3ae4a0fd3c', lineNumber=1}]}

๋ชจ๋“  13 ๋Œ“๊ธ€

SQL์— ์ด์ƒํ•œ ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์™œ ์šฐ๋ฆฌ๋Š” ์‹ฌ์ง€์–ด ์‚ฌ์šฉํ•˜๋Š” top n ๋Œ€์‹  offset ... fetch ... . ๊ทธ๋ฆฌ๊ณ  ์™œ ์ค‘๋ณต ๊ด„ํ˜ธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๊นŒ?

Panache๊ฐ€ ์ฟผ๋ฆฌ์— setMaxResults() ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ถ”์ธกํ•ฉ๋‹ˆ๋‹ค.

๊ธ€์Ž„, ๊ทธ๊ฒƒ์€ ํ™•์‹คํžˆ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Panache๋Š” ์ž์ฒด์ ์ธ SQL ์ƒ์„ฑ์„ ํ•˜๊ณ  ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @FroMage?

๊ธ€์Ž„, ๋‚˜๋Š” ์ด๊ฒƒ์„ ์ผ๋ฐ˜ HR์—์„œ ์‹œ๋„ํ–ˆ๊ณ  ๋‚˜๋Š” ๋‹ค์Œ์„ ์–ป๋Š”๋‹ค.

select hqlquerypa0_.id as id1_0_, hqlquerypa0_.description as descript2_0_, hqlquerypa0_.name as name3_0_, hqlquerypa0_.type as type4_0_ from Flour hqlquerypa0_ order by hqlquerypa0_.id offset <strong i="6">@P1</strong> rows fetch next <strong i="7">@P2</strong> rows only

๊ทธ๋ž˜์„œ ์ด๊ฒƒ์€ Panache์™€ ๊ด€๋ จ๋œ ๋ฌธ์ œ์ž„์— ํ‹€๋ฆผ์—†๋‹ค๊ณ  ์ƒ๊ฐ๋ฉ๋‹ˆ๋‹ค.

๊ฒ€ํ† ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์Šคํƒ์— ์žˆ๋Š” ์ผ๋ถ€ ํ”„๋กœ์ ํŠธ์— ์—ฐ๋ฝํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ถ”์  ๋กœ๊ทธ์— ํ‘œ์‹œ๋œ ์œ ์ผํ•œ HQL ๋•Œ๋ถ€ํ„ฐ FROM myproject.entities.Request WHERE requestor.firstName LIKE ?1 , ๋‚˜๋Š”์˜ ์ถ”๊ฐ€ ๊ฐ€์ • top(?) ์— ๋Œ€ํ•œ MS SQL ๊ตฌํ˜„์—์„œ์˜ค๊ณ  setMaxResults() ๊ฒŒ์‹œ๋ฌผ์—, ๊ทธ๋Ÿฌ๋‚˜ SQL์„ ์™„์ „ํžˆ ๋‹ค๋ฅธ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Œ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์—ฌ์ „ํžˆ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ๋‹ค์Œ HQL์„ ์‚ฌ์šฉํ•˜๋„๋ก ์ฃผ๋ฌธ์„ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค. FROM myproject.entities.Request WHERE requestor.firstName LIKE ?1 ORDER BY submitted

2021-08-05 16:20:37,992 DEBUG [org.hib.hql.int.ast.QueryTranslatorImpl] (vert.x-eventloop-thread-19) HQL: FROM myproject.entities.Request WHERE requestor.firstName LIKE ?1 ORDER BY submitted
2021-08-05 16:20:37,992 DEBUG [org.hib.hql.int.ast.QueryTranslatorImpl] (vert.x-eventloop-thread-19) SQL: select request0_.id as id1_1_, request0_.caseId as caseid2_1_, request0_.caseNumber as casenumb3_1_, request0_.expires as expires4_1_, request0_.addressLine1 as addressl5_1_, request0_.addressLine2 as addressl6_1_, request0_.agency as agency7_1_, request0_.city as city8_1_, request0_.email as email9_1_, request0_.firstName as firstna10_1_, request0_.lastName as lastnam11_1_, request0_.phone as phone12_1_, request0_.relationship as relatio13_1_, request0_.state as state14_1_, request0_.zipcode as zipcode15_1_, request0_.submitted as submitt16_1_ from Request request0_ where request0_.firstName like ? order by request0_.submitted

์ด๊ฒƒ์€ ๋‹ค์Œ SQL์„ ์‹คํ–‰ํ•˜๋ ค๊ณ  ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.

2021-08-05 16:20:38,022 DEBUG [org.hib.SQL] (vert.x-eventloop-thread-19)
    select
        request0_.id as id1_1_,
        request0_.caseId as caseid2_1_,
        request0_.caseNumber as casenumb3_1_,
        request0_.expires as expires4_1_,
        request0_.addressLine1 as addressl5_1_,
        request0_.addressLine2 as addressl6_1_,
        request0_.agency as agency7_1_,
        request0_.city as city8_1_,
        request0_.email as email9_1_,
        request0_.firstName as firstna10_1_,
        request0_.lastName as lastnam11_1_,
        request0_.phone as phone12_1_,
        request0_.relationship as relatio13_1_,
        request0_.state as state14_1_,
        request0_.zipcode as zipcode15_1_,
        request0_.submitted as submitt16_1_
    from
        Request request0_
    where
        request0_.firstName like <strong i="10">@P1</strong>
    order by
        request0_.submitted offset 0 rows fetch next ? rows only

๊ทธ๋ž˜์„œ ... ๋งค๊ฐœ ๋ณ€์ˆ˜ ๋Œ€์ฒด๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์•˜๋‹ค๋Š” ์ ์—์„œ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์—ฌ์ „ํžˆ ์กด์žฌํ•˜์ง€๋งŒ (ํ˜„์žฌ fetch next ? rows only ) ์ƒ์„ฑ ๋œ SQL ๊ตฌ๋ฌธ์ด ์˜ˆ์ œ์™€ ์ผ์น˜ํ•˜๋„๋ก ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Quarkus์—๋Š” ์•„์ง hibernate-reactive-core 1.0.0.CR9๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฒ„์ „๊ณผ hibernate-core 5.5.5.Final์— ๋Œ€ํ•œ ๋‚ด pom์˜ ๋ฒ„์ „์„ ํŠน๋ณ„ํžˆ ๋ฎ์–ด์ผ์Šต๋‹ˆ๋‹ค. ์˜์กด์„ฑ์„ ๋†“์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” Hibernate ์ฟผ๋ฆฌ๊ฐ€ Panache io.quarkus.hibernate.reactive.panache.common.runtime.CommonPanache QueryImpl:L254 ์—์„œ ์ƒ์„ฑ๋˜์—ˆ๋‹ค๊ณ  ๋ฏฟ๋Š” ๊ณณ์„ ๋ณด์•˜๊ณ  setFirstResult ๋ฐ setMaxResults ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ์ฟผ๋ฆฌ์—. ๋””๋ฒ„๊ฑฐ์—์„œ ์ฟผ๋ฆฌ ๊ฐœ์ฒด๋ฅผ ๋ณด์•˜๊ณ  ํ•ด๋‹น createQuery ๋ฉ”์„œ๋“œ์˜ ๋์—์„œ ๊ธฐ๋ณธ ReactiveQueryImpl์—๋Š” firstRow=0 ๋ฐ maxRows=25๋ฅผ ํฌํ•จํ•˜๋Š” queryOptions๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋„์›€์„ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! (๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Œ์„ ์ดํ•ด)

SQLServerParameters.processLimit() ์—์„œ ๋ฒ„๊ทธ๋ฅผ ์ฐพ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Panache๋Š” firstRow=0์ธ ์ตœ๋Œ€ ์ ˆ์ „ ๋ชจ๋“œ ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

org.hibernate.reactive.loader.ReactiveLoader.executeReactiveQueryStatement ๋‚ด๋ถ€์—์„œ SQLServer2012LimitHandler.getOffsetFetch() ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

if ( !LimitHelper.hasFirstRow( selection ) ) {
    return " offset 0 rows fetch next ? rows only";
}
return " offset ? rows fetch next ? rows only";

๋”ฐ๋ผ์„œ ์ด ์‹œ์ ์˜ SQL์€ offset 0 rows fetch next ? rows only ๋๋‚ฉ๋‹ˆ๋‹ค. ? ๋Œ€์‹  0์— ์œ ์˜ํ•˜์‹ญ์‹œ์˜ค.
SQLServerParameters.processLimit() :

        if (isProcessingNotRequired(sql)) {
            return sql;
        }

        // Replace 'offset ? fetch next ? rows only' with the <strong i="17">@P</strong> style parameters for Sql Server
        int index = hasOffset ? parameterArray.length - 1 : parameterArray.length;
        int pos = sql.indexOf( " offset ?" );
        if ( pos > -1 ) {
            String sqlProcessed = sql.substring( 0, pos ) + " offset @P" + index++ + " rows";
            if ( sql.indexOf( " fetch next ?" ) > -1 ) {
                sqlProcessed += " fetch next @P" + index + " rows only ";
            }
            return sqlProcessed;
        }

        return sql;

sql.indexOf( " offset ?") ๊ฐ€ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. LimitHandler๊ฐ€ ์ด๋ฏธ ์˜คํ”„์…‹์„ 0์œผ๋กœ ํ•˜๋“œ ์ฝ”๋”ฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•˜์œ„ ๋ฌธ์ž์—ด offset ? ์ฐพ์„ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ์ถ”๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
fetch next ? ์ฐพ๋Š” ์ค‘์ฒฉ ๋ฌธ์ž์—ด ์ผ์น˜๋ฅผ offset ์— ๋Œ€ํ•œ ์ผ์น˜ ์™ธ๋ถ€๋กœ ์ด๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

@bharward Hibernate Reactive๋งŒ์„ ์‚ฌ์šฉํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋งค์šฐ ๊ฐ์‚ฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Panache๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ €์žฅ์†Œ๋„ ์‚ดํŽด๋ด์•ผ๊ฒ ์ง€๋งŒ ์ด ์ €์žฅ์†Œ๋Š” ๊ทธ๋Ÿฐ ์ข…๋ฅ˜์˜ ๋ฌธ์ œ์— ์ ํ•ฉํ•œ ์žฅ์†Œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

์ฒซ ๋ฒˆ์งธ ๊ฒฐ๊ณผ๊ฐ€ ์•„๋‹Œ ์ตœ๋Œ€ ๊ฒฐ๊ณผ๋งŒ ์„ค์ •ํ•˜๋Š” ํ…Œ์ŠคํŠธ๊ฐ€ ๋ˆ„๋ฝ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@gavinking ๋ฐ @DavidD - ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. setFirstResult(0) ๋ฐ setMaxResults(n) (n์€ ์ž„์˜์˜ ๊ฐ’ > 0) _๋‘˜ ๋‹ค ์ˆ˜ํ–‰ํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ๊ฐ€ ๋‚ด๊ฐ€ ๋ณด๊ณ  ์žˆ๋Š” ์˜ค๋ฅ˜๋ฅผ ์žฌํ˜„ํ•  ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.

SQLServer2012LimitHandler.getOffsetFetch() firstResult==0("offset 0 rows...")์ผ ๋•Œ์™€ firstResult >0("offset ? rows");

๊ทธ๋ž˜๋„ ๋„์›€์ด ๋œ๋‹ค๋ฉด ๋ช‡ ์ผ ์•ˆ์— ์žฌํ˜„ํ•  ์ž‘์€ HR ์ „์šฉ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋‚ด๊ฐ€ ์„ค๋ช…ํ•œ ๋Œ€๋กœ HQLQueryParameterNamedLimitTest๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์„ ํ• ์• ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„, ๋งž์Šต๋‹ˆ๋‹ค. ์ด ํ…Œ์ŠคํŠธ๋Š” HQLQueryParameterNamedLimitTest ์—์„œ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

    <strong i="7">@Test</strong>
    public void testFirstResultZeroAndMaxResults(TestContext context) {
        test(
                context,
                openSession()
                        .thenCompose( s ->
                                s.createQuery( "from Flour order by id" )
                                        .setFirstResult( 0 )
                                        .setMaxResults( 10 )
                                        .getResultList()
                                        .thenAccept( result -> {
                                            context.assertEquals( 3, result.size() );
                                        } )
                        )
        );
    }

๋‚ด๊ฐ€ ๋ด์ค„๊ฒŒ

@DavidD _์ถ”๊ฐ€๋กœ_ ์ œ์•ˆํ•œ ํ…Œ์ŠคํŠธ ์™ธ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ถ”๊ฐ€ ํ…Œ์ŠคํŠธ๋„ ์ œ์•ˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

       <strong i="7">@Test</strong>
    public void testFirstResultZeroAndMaxResultsWithoutOrderBy(TestContext context) {
        test(
                context,
                openSession()
                        .thenCompose( s ->
                                s.createQuery( "from Flour" )
                                        .setFirstResult( 0 )
                                        .setMaxResults( 10 )
                                        .getResultList()
                                        .thenAccept( result -> {
                                            context.assertEquals( 3, result.size() );
                                        } )
                        )
        );
    }

์ฐจ์ด์ ์€ "order by"๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค SQLServer2005LimitHandler์ด ๊ฐ™์€ ์ฟผ๋ฆฌ๋ฅผ ๊ธฐ๋ก select top(?) ... ์ฟผ๋ฆฌ๋Š” "์— ์˜ํ•ด ์ˆœ์„œ"๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š์„ ๋•Œ๋งˆ๋‹ค,ํ•˜์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒ๋˜๋ฉด ๊ทธ๊ฒƒ์€ ์‚ฌ์šฉ offset ? fetch next ? ๊ตฌ๋ฌธ์„. ๊ทธ๋ž˜์„œ 2๊ฐœ์˜ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋งค์šฐ ๊ฐ์‚ฌ!!

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰