fix(support): use JDSL model for count query to bypass strict JPQL parsers#1040
fix(support): use JDSL model for count query to bypass strict JPQL parsers#1040shouwn merged 4 commits intoline:developfrom
Conversation
298a721 to
2f6e71d
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #1040 +/- ##
===========================================
+ Coverage 90.51% 90.76% +0.24%
===========================================
Files 360 360
Lines 3805 3842 +37
Branches 231 239 +8
===========================================
+ Hits 3444 3487 +43
+ Misses 294 287 -7
- Partials 67 68 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
2f6e71d to
acea337
Compare
There was a problem hiding this comment.
Pull request overview
This PR fixes a BadJpqlGrammarException that occurs in Spring Boot 4 (Spring Data JPA 3.4+) environments when using pagination with queries containing NULL literals or complex expressions in SELECT NEW clauses. The fix replaces fragile string-based count query generation with a robust model-based approach using Kotlin JDSL's internal Query Model.
Changes:
- Added
SelectQueries.toCountQuery()utility to transform SelectQuery into COUNT(1) query at the model level - Updated JpqlEntityManagerUtils in both spring-data-jpa and spring-data-jpa-boot4 modules to use model-based count query generation
- Added integration tests (Issue1039Test.kt) in example projects to verify the fix
- Enhanced unit tests to cover both model-based and fallback count query paths
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt | Added toCountQuery() factory method to transform SelectQuery into COUNT query at model level |
| support/spring-data-jpa/src/main/kotlin/com/linecorp/kotlinjdsl/support/spring/data/jpa/JpqlEntityManagerUtils.kt | Replaced string-based count query with model-based approach, added fallback for non-select queries |
| support/spring-data-jpa-boot4/src/main/kotlin/com/linecorp/kotlinjdsl/support/spring/data/jpa/JpqlEntityManagerUtils.kt | Applied same model-based count query logic for Boot4 compatibility |
| support/spring-data-jpa/src/test/kotlin/com/linecorp/kotlinjdsl/support/spring/data/jpa/JpqlEntityManagerUtilsTest.kt | Added @OptIn for Internal APIs, split tests to cover model-based and fallback paths |
| support/spring-data-jpa-boot4/src/test/kotlin/com/linecorp/kotlinjdsl/support/spring/data/jpa/JpqlEntityManagerUtilsTest.kt | Enhanced tests to cover both query generation paths |
| support/spring-data-jpa-boot4/src/main/kotlin/org/springframework/data/jpa/repository/query/QueryEnhancerFactoryAdaptor.kt | Removed redundant import declarations |
| example/spring-data-jpa/src/test/kotlin/com/linecorp/kotlinjdsl/example/spring/data/jpa/jpql/select/Issue1039Test.kt | Added integration test reproducing and verifying the fix for Issue #1039 |
| example/spring-data-jpa-boot4/src/test/kotlin/com/linecorp/kotlinjdsl/example/spring/data/jpa/jpql/select/Issue1039Test.kt | Added Boot4-specific integration test for the issue |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...y-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt
Outdated
Show resolved
Hide resolved
...y-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt
Outdated
Show resolved
Hide resolved
...y-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt
Show resolved
Hide resolved
...y-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt
Outdated
Show resolved
Hide resolved
...y-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt
Show resolved
Hide resolved
...rc/test/kotlin/com/linecorp/kotlinjdsl/support/spring/data/jpa/JpqlEntityManagerUtilsTest.kt
Show resolved
Hide resolved
...y-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt
Outdated
Show resolved
Hide resolved
acea337 to
160638a
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...y-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt
Show resolved
Hide resolved
...y-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt
Show resolved
Hide resolved
...y-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt
Outdated
Show resolved
Hide resolved
...src/test/kotlin/com/linecorp/kotlinjdsl/example/spring/data/jpa/jpql/select/Issue1039Test.kt
Show resolved
Hide resolved
1be56c0 to
2701f64
Compare
2701f64 to
a5a0a4c
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...y-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt
Outdated
Show resolved
Hide resolved
...pa/src/main/kotlin/com/linecorp/kotlinjdsl/support/spring/data/jpa/JpqlEntityManagerUtils.kt
Show resolved
Hide resolved
a5a0a4c to
0e78f67
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...pa/src/main/kotlin/com/linecorp/kotlinjdsl/support/spring/data/jpa/JpqlEntityManagerUtils.kt
Outdated
Show resolved
Hide resolved
.../main/kotlin/com/linecorp/kotlinjdsl/support/spring/data/jpa/javax/JpqlEntityManagerUtils.kt
Outdated
Show resolved
Hide resolved
...y-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...src/test/kotlin/com/linecorp/kotlinjdsl/example/spring/data/jpa/jpql/select/Issue1039Test.kt
Show resolved
Hide resolved
...src/test/kotlin/com/linecorp/kotlinjdsl/example/spring/data/jpa/jpql/select/Issue1039Test.kt
Show resolved
Hide resolved
...del/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueriesTest.kt
Outdated
Show resolved
Hide resolved
9f7f72d to
8cecb38
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...rc/test/kotlin/com/linecorp/kotlinjdsl/support/spring/data/jpa/JpqlEntityManagerUtilsTest.kt
Show resolved
Hide resolved
...rc/test/kotlin/com/linecorp/kotlinjdsl/support/spring/data/jpa/JpqlEntityManagerUtilsTest.kt
Outdated
Show resolved
Hide resolved
af889c4 to
6f189ac
Compare
6f189ac to
a953917
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...y-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt
Show resolved
Hide resolved
...y-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/select/SelectQueries.kt
Show resolved
Hide resolved
a953917 to
292ee0f
Compare
- Use COUNT(1) for non-distinct queries for accuracy and compatibility. - Reuse QueryEnhancer in JpqlEntityManagerUtils to avoid redundant parsing. - Strip FETCH attribute from joins in count queries to prevent JPA errors. - Refine KDoc for toCountQuery and add warnings for groupBy/having results. - Update tests to verify clause preservation and COUNT(1) behavior.
292ee0f to
12d2293
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Motivation
BadJpqlGrammarExceptionthat occurs in Spring Boot 4 (Spring Data JPA 3.4+) environments when usingfindPagewith certain valid JPQL constructs.NULLwithinSELECT NEWconstructor expressions.Modifications
SelectQueries.toCountQuery()utility in thequery-model-jpqlmodule. This allows safe transformation of aSelectQueryinto aCOUNT(1)query at the model level.JpqlEntityManagerUtils.ktin bothsupport/spring-data-jpaandsupport/spring-data-jpa-boot4modules to use this model-based approach for generating count queries.copy()warnings (KT-11914) by encapsulating the transformation logic within the same module as theinternalconstructors.Issue1039Test.ktin bothexample/spring-data-jpaandexample/spring-data-jpa-boot4to reproduce the reported issue and verify the fix.JpqlEntityManagerUtilsTest.ktto cover the new model-based execution path.Result
findPage) for queries containingNULLliterals or other complex expressions inSELECT NEWclauses on Spring Boot 4.Closes
#1039
--- korean
Motivation
findPage호출 시 일부 유효한 JPQL 구문에 대해 발생하는BadJpqlGrammarException을 해결합니다.SELECT NEW생성자 내의NULL키워드 등을 거부하는 문제를 해결하기 위함입니다.QueryEnhancer) 대신 Kotlin JDSL의 쿼리 모델(Query Model) 을 직접 조작하여 카운트 쿼리를 생성함으로써 근본적이고 프로바이더 중립적인 해결책을 제공합니다.Modifications
query-model-jpql모듈에SelectQueries.toCountQuery()유틸리티를 추가하여 모델 수준에서SelectQuery를COUNT(1)쿼리로 안전하게 변환하도록 했습니다.support/spring-data-jpa및support/spring-data-jpa-boot4모듈의JpqlEntityManagerUtils.kt가 문자열 파서 대신 이 모델 기반 방식을 사용하도록 수정했습니다.internal생성자 접근으로 인한 Kotlincopy()경고(KT-11914)를 변환 로직의 모듈 내 캡슐화를 통해 해결했습니다.example/spring-data-jpa및example/spring-data-jpa-boot4에Issue1039Test.kt를 추가하여 문제를 재현하고 해결 여부를 검증했습니다.JpqlEntityManagerUtilsTest.kt를 업데이트하여 모델 기반 카운트 쿼리 생성 경로를 테스트하도록 보강했습니다.Result
SELECT NEW절에NULL리터럴 등이 포함된 쿼리에 대해 페이지네이션(findPage) 기능을 정상적으로 사용할 수 있습니다.Closes
#1039