-
-
Notifications
You must be signed in to change notification settings - Fork 974
Expand Hibernate 7 functional coverage and query parity #15731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jamesfredley
wants to merge
44
commits into
8.0.x-hibernate7
Choose a base branch
from
test/h7-functional-coverage
base: 8.0.x-hibernate7
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
d7d9e7d
ci: unify functional test CI to run all tests against both Hibernate …
jamesfredley e2336d9
fix: register h7 autoconfig and remove h5-specific ehcache config
jamesfredley f587be1
ci: skip h7-incompatible general tests when running with hibernateVer…
jamesfredley fbfe66b
fix: make gorm and app1 functional tests H7-compatible
borinquenkid a458c4a
fix(h7): fix 3 H7 GORM bugs — NonUniqueResultException, aggregate ret…
borinquenkid 707c33d
fix(h7): prevent 'two representations of same collection' in addTo/sa…
borinquenkid a63dcad
fix(test): correct GormCriteriaQueriesSpec to use safe HQL overloads …
borinquenkid dc7c4a0
address PR feedback: validate hibernateVersion, rename booleans, fix …
jamesfredley b92f3d5
Merge remote-tracking branch 'origin/8.0.x-hibernate7' into ci/hibern…
jamesfredley 5a97cbe
fix(ci): substitute grails-bom with grails-hibernate7-bom for H7 func…
jamesfredley 5fa3c96
fix(ci): align hibernate to 7.2.7 and fix grails-bom publication path
jamesfredley 3f8eb79
fix(ci): swap project(':grails-bom') for h7, add micronaut-bom to for…
jamesfredley b59c548
fix(ci): attach grails-hibernate7-bom platform to test project depend…
jamesfredley 904fd76
fix(ci): pin testcontainers BOM in grails-forge-analytics-postgres
jamesfredley 5db69b2
fix(ci): correct testcontainers artifact name to org.testcontainers:p…
jamesfredley 52ba29e
fix(ci): correct testcontainers spock artifact in grails-forge-cli
jamesfredley cf6d9ce
chore(forge): move testcontainers version to gradle.properties
jamesfredley 634c9e8
Merge branch '8.0.x-hibernate7' into ci/hibernate-matrix-testing
jamesfredley 8b7958a
Merge remote-tracking branch 'origin/ci/hibernate-matrix-testing' int…
jamesfredley 62e54ff
Require Hibernate functional checks before publish
jamesfredley 5aaa296
Align Hibernate 7 functional dependency routing
jamesfredley 794ce68
Match Hibernate 7 static finder parity
jamesfredley 6d0aaa5
Apply Hibernate 7 HQL query settings consistently
jamesfredley b269c00
Restore migrated Hibernate 7 TCK spec wiring
jamesfredley d4963e7
Fix Hibernate 7 has-many support import
jamesfredley 49c8064
Scan Hibernate 7 multitenancy support package
jamesfredley 74bfe69
Document Hibernate 7 HQL query settings
jamesfredley fcf88e9
Document Hibernate 7 finder and getAll behavior
jamesfredley da46aed
Mark H7 GORM bug report historical
jamesfredley 2e02653
Normalize H7 GORM bug report typography
jamesfredley 00b1e05
Address Hibernate 7 review feedback
jamesfredley fd42df2
Merge branch '8.0.x-hibernate7' into test/h7-functional-coverage
jamesfredley 94efeeb
Resolve Hibernate 7 functional coverage blockers
jamesfredley a1126fc
docs(h7): mark Bugs 2, 3, 4, and 5 as fixed in report
borinquenkid b5af3b8
Align Hibernate models with Spring Boot managed ORM
jamesfredley de0d94a
Align Hibernate 7.4 dependency APIs
jamesfredley 724dab7
Remove Hibernate proxy fallback workaround
jamesfredley 38c0db8
Let Hibernate create simple ID primary keys
jamesfredley ad00e95
Fix composite ID association column ordering
jamesfredley 36026fc
Update identity generator spec for Hibernate 7.4
jamesfredley 0b867ca
Update event listener spec for Hibernate 7.4
jamesfredley a5cd019
Document Hibernate 7.4 migration checklist
jamesfredley 7c991ad
refactor: move composite FK sorting logic into HibernatePersistentPro…
borinquenkid 3ee18b8
Refactor generator mapped identity logic in BasicValueCreator
borinquenkid File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| <!-- | ||
| SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||
| you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
|
|
||
| https://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| --> | ||
|
|
||
| ## Historical H7 `gorm` Functional Test Failures - Bug Report | ||
|
|
||
| This historical report captured the `grails-test-examples-gorm` failures that drove the Hibernate 7 fixes in this branch. Some entries below have since been fixed by this branch, so treat this file as triage rationale rather than current expected test status. | ||
|
|
||
| Before those fixes, running `grails-test-examples-gorm` with `-PhibernateVersion=7` produced 13 failures across 4 specs. Below are the 5 distinct root causes. | ||
|
|
||
| --- | ||
|
|
||
| ### Bug 1 (Intentional) - `executeQuery` / `executeUpdate` plain String blocked | ||
|
|
||
| | | | | ||
| |---|---| | ||
| | **Tests** | `test basic HQL query`, `test HQL aggregate functions`, `test HQL group by`, `test executeUpdate for bulk operations` | | ||
| | **Spec** | `GormCriteriaQueriesSpec` | | ||
| | **Error** | `UnsupportedOperationException: executeQuery(CharSequence) only accepts a Groovy GString with interpolated parameters` | | ||
|
|
||
| **Description:** H7 intentionally rejects `executeQuery("from Book where inStock = true")` when no parameters are passed. The same tightening was already applied to `executeUpdate`. Callers must use `executeQuery('...', [:])` or a GString with interpolated params. | ||
|
|
||
| > This is by design. The test bodies need to adopt the parameterized form - not a GORM bug. | ||
|
|
||
| --- | ||
|
|
||
| ### Bug 2 (Fixed) - `DetachedCriteria.get()` throws `NonUniqueResultException` instead of returning first result | ||
|
|
||
| | | | | ||
| |---|---| | ||
| | **Test** | `test detached criteria as reusable query` | | ||
| | **Spec** | `GormCriteriaQueriesSpec:454` | | ||
| | **Error** | `jakarta.persistence.NonUniqueResultException: Query did not return a unique result: 2 results were returned` | | ||
|
|
||
| **Description:** H5 `DetachedCriteria.get()` returned the first matching row when multiple rows existed. H7's `AbstractSelectionQuery.getSingleResult()` is now strict and throws if the result is not unique. | ||
|
|
||
| **Expected fix:** `HibernateQueryExecutor.singleResult()` should apply `setMaxResults(1)` before calling `getSingleResult()`, or switch to `getResultList().stream().findFirst()`. | ||
|
|
||
| > **Status:** Fixed. Caught exceptions are updated to check for `jakarta.persistence.NonUniqueResultException` to return the first result, and the tests pass. | ||
|
|
||
| --- | ||
|
|
||
| ### Bug 3 (Fixed) - `Found two representations of same collection: gorm.Author.books` | ||
|
|
||
| | | | | ||
| |---|---| | ||
| | **Tests** | `test saving child with belongsTo saves parent reference`, `test dirty checking with associations`, `test belongsTo allows orphan removal`, `test updating multiple children`, `test addTo creates bidirectional link` | | ||
| | **Spec** | `GormCascadeOperationsSpec` | | ||
| | **Error** | `HibernateSystemException: Found two representations of same collection: gorm.Author.books` | | ||
|
|
||
| **Description:** H7 enforces stricter collection identity. After `author.addToBooks(book); author.save(flush: true)`, the session contains two references to the same `Author.books` collection, causing a `HibernateException` on flush. H5 tolerated this. | ||
|
|
||
| **Expected fix:** GORM's `addTo*` / cascade-flush path in `grails-data-hibernate7` must synchronize both sides of the bidirectional association and merge/evict stale collection snapshots before flushing. | ||
|
|
||
| > **Status:** Fixed. Cascade flush issues and collection representations are now resolved, and `GormCascadeOperationsSpec` passes 100%. | ||
|
|
||
| --- | ||
|
|
||
| ### Bug 4 (Fixed) - `@Query` aggregate functions fail with type mismatch | ||
|
|
||
| | | | | ||
| |---|---| | ||
| | **Tests** | `test findAveragePrice`, `test findMaxPageCount` | | ||
| | **Spec** | `GormDataServicesSpec` | | ||
| | **Errors** | `Incorrect query result type: query produces 'java.lang.Double' but type 'java.lang.Long' was given` / `query produces 'java.lang.Integer' but type 'java.lang.Long' was given` | | ||
|
|
||
| **Description:** `HibernateHqlQuery.buildQuery()` always calls `session.createQuery(hql, ctx.targetClass())`. For aggregate HQL (`select avg(b.price) ...`, `select max(b.pageCount) ...`), the query does not return an entity, but `ctx.targetClass()` returns the entity class (e.g., `Book`). H7's `SqmQueryImpl` enforces strict result-type alignment: `avg()` produces `Double`, `max(pageCount)` produces `Integer`, neither is coercible to the bound entity type. | ||
|
|
||
| **Expected fix:** `HibernateHqlQuery.buildQuery()` must detect non-entity HQL (aggregates / projections) and call the untyped `session.createQuery(hql)` in those cases, letting GORM handle result casting downstream. | ||
|
|
||
| > **Status:** Fixed. Aggregate return types are now dynamically resolved, matching the expected Java type of the aggregate function itself. | ||
|
|
||
| --- | ||
|
|
||
| ### Bug 5 (Fixed) - `where { pageCount > price * 10 }` fails with `CoercionException` | ||
|
|
||
| | | | | ||
| |---|---| | ||
| | **Test** | `test where query comparing two properties` | | ||
| | **Spec** | `GormWhereQueryAdvancedSpec:175` | | ||
| | **Error** | `org.hibernate.type.descriptor.java.CoercionException: Error coercing value` | | ||
|
|
||
| **Description:** A where-DSL closure comparing an `Integer` property (`pageCount`) to an arithmetic expression involving a `BigDecimal` property (`price * 10`) worked in H5. H7's SQM type system no longer allows implicit coercion between `Integer` and `BigDecimal` in a comparison predicate. | ||
|
|
||
| **Expected fix:** The GORM where-query-to-SQM translator should emit an explicit `CAST` in the SQM tree when the two operands of a comparison have different numeric types. | ||
|
|
||
| > **Status:** Fixed. Type coercion in comparison predicates is now handled, and `GormWhereQueryAdvancedSpec` passes 100%. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@borinquenkid my issue is this file, specifically this substitution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Hey @jdaugherty, that makes total sense. In an OSS context, hidden classpath manipulation like this easily rots if left unchecked, and I agree we don't want people troubleshooting brittle IDE syncs locally.
Here is compromise so we can hit our end-of-June release target for Hibernate 7 parity without abandoning your architectural goal:
Fail-Safe Logging: I will add an explicit, loud deprecation warning or a hardcoded TODO block directly above this substitution in functional-test-config.gradle tracking its removal.
Immediate Post-Release Issue: I'll open a tracking issue right now to completely untangle this layer by cloning the apps into a clean directory structure.
Given that I want to completely drop Hibernate 5 support in the near future anyway, duplicating the entire H5 test matrix right this second might end up being throwaway work. Can we use this substitution as a temporary bridge to unblock the June release gate, with the explicit agreement that the cleanup issue is the immediate next priority?"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm strongly a -1 on this. People will just ignore the depreciation and it doesn't solve our actual problem. The majority of the work I've done with Grails is dependency debugging - probably over 50% of my time has been spent on it. This completely breaks that workflow. By substituting arbitrarily, we now have to populate that option throughout our workflows to be able to debug.