Conversation
### Build issue **Issue** misconfiguration of grails-data-tck-config.gradle and core build.gradle ### Global Naming Strategy Pollution (Fixed) **Issue:** `GrailsDomainBinder` used a static `NamingStrategyProvider`, causing naming strategies configured in one test to persist into others. **Action:** Refactored `NamingStrategyProvider` into an instance-based field. Updated `GrailsDomainBinder`, `HibernateMappingContextConfiguration`, and `HibernateConnectionSourceFactory` to pass this instance through the configuration lifecycle. ### Static Mapping Cache (Fixed) **Issue:** `MappingCacheHolder` was a static singleton. While `HibernateDatastore` attempted to clear it, direct usage of binders in unit tests often bypassed this cleanup, leading to stale mappings persisting between tests. **Action:** Refactored `MappingCacheHolder` to remove the static singleton (`getInstance()`). The cache is now instance-based and maintained by `HibernateMappingContext`. All consumers (`GrailsDomainBinder`, `HibernateDatastore`, `HibernateHqlQuery`, etc.) were updated to use the instance tied to their specific configuration cycle, eliminating cross-test pollution.
### Mapping Closure Evaluation Bug (Fixed)
**Issue:** In `HibernateMappingBuilder.groovy`, the `index` property was being aggressively converted to a `String` via `.toString()`. When a closure was provided (e.g., `index: { column 'foo' }`), the internal Groovy closure class name was stored instead of the closure itself, preventing proper evaluation during the second pass.
**Action:** Removed the premature `.toString()` conversion in `HibernateMappingBuilder.handlePropertyInternal`.
### Named Unique Constraints Support (Implemented)
**Issue:** During the exploration of `ColumnConfig` possibilities, it was noted that the `unique` property was restricted to `boolean`, preventing the use of named unique constraints (uniqueness groups) via the DSL.
**Action:** Transitioned `unique` to `Object` in `ColumnConfig.groovy` and added an `isUnique()` helper for Java compatibility. Updated `HibernateMappingBuilder` and `ColumnConfigToColumnBinder` to handle the flexible type. This now allows configuration like `unique: 'groupName'` or `unique: ['group1', 'group2']` through the mapping DSL.
### Multi-Column Property Re-evaluation Bug (Fixed)
**Issue:** Found a bug in `PropertyDefinitionDelegate` where re-evaluating a property with multiple columns would always overwrite the first column instead of correctly updating subsequent ones.
**Action:** Fixed `PropertyDefinitionDelegate` to use the current `index` when accessing existing `ColumnConfig` objects. Added `PropertyDefinitionDelegateSpec` to verify the fix.
* Criteria Query NPE: Fixed NullPointerException in JpaFromProvider by implementing projection-aware auto-joining for association paths. * Subquery Join Leakage: Resolved PathElementException by isolating subquery joins and preventing them from leaking into the outer query scope. * Multi-Tenancy Regression: Restored missing PreQueryEvent and PostQueryEvent publication in HibernateQuery to ensure tenant filters are correctly applied. * HQL Parameter Binding: Fixed QueryParameterException by filtering GORM-specific query settings (e.g., flushMode) from named parameters in executeQuery. * Parameterized String Queries: Added support for executeQuery and executeUpdate overloads that accept plain String queries with positional/named parameters. * Multi-Column Mapping Bug: Fixed a bug in PropertyDefinitionDelegate where re-evaluating properties with multiple columns would overwrite the first column. * Mapping DSL Index Fix: Resolved a .toString() conversion bug for index closures in HibernateMappingBuilder. * Test Suite Modernization: Consolidated legacy HibernateMappingBuilder tests into a modern Spock specification and added verification for multi-column property logic.
* Criteria Queries: Fixed NullPointerException in projections via auto-joining and isolated subquery joins to prevent path leakage.
* Multi-Tenancy: Restored PreQueryEvent and PostQueryEvent publication to ensure tenant filters are correctly applied.
* DDL & Precision: Implemented dialect-aware precision defaulting (15 digits) for non-Oracle databases to avoid invalid float(64) generation.
* Query Parameters: Filtered internal GORM settings (e.g., flushMode) from HQL named parameters to prevent binding exceptions.
* Mapping DSL: Fixed a bug where index closures were incorrectly converted to strings and improved unique property assignment.
* Robustness: Added explicit checks for uninitialized identifier generators to provide descriptive error messages instead of NullPointerException.
HibernateQuery Event ClassCastException **Symptoms:** - `java.lang.ClassCastException: class org.grails.datastore.mapping.query.event.PreQueryEvent cannot be cast to class org.grails.datastore.mapping.engine.event.AbstractPersistenceEvent` **Description:** The event listener in `HibernateQuerySpec` incorrectly expects `AbstractPersistenceEvent` while `PreQueryEvent` and `PostQueryEvent` now extend `AbstractQueryEvent`.
HibernateQuerySpec fixed to implementation
JpaFromProvider fixed
JpaCriteriaQueryCreator cleaned up and spec fixed
PredicateGenerator cleaned up and spec fixed
Following the pattern used in Hibernate 5, I have moved the vendored Spring Framework ORM Hibernate 7 integration classes from the core module to a dedicated spring-orm module:
- Created Module: grails-data-hibernate7-spring-orm (located in grails-data-hibernate7/spring-orm).
- Moved Classes: All classes in org.grails.orm.hibernate.support.hibernate7 (including HibernateTransactionManager, HibernateTemplate, LocalSessionFactoryBean, etc.) are now in the new module.
- Updated Dependencies:
- Added the new module to settings.gradle.
- Updated grails-data-hibernate7-core, grails-plugin, boot-plugin, and dbmigration to depend on the new spring-orm module.
- Updated gradle/publish-root-config.gradle to ensure the new module is included in the publishing process.
- HibernateDetachedCriteria.isNumericPropertyType: box primitive types before the Number.isAssignableFrom check so that domains declaring numeric properties as primitives (int/long/double/float/short/byte) work correctly in where-DSL arithmetic expressions. Method is protected to allow subclass overrides. - ToManyEntityMultiTenantFilterBinder.bind: add null guard for getHibernateAssociatedEntity() return value to prevent NullPointerException on partially-resolved associations. - grails-data-hibernate7/README.md: add grails-data-hibernate7-spring-orm to the Module Structure table. - Tests: new HibernateDetachedCriteriaSpec covering boxed and all 6 primitive numeric types, non-numeric delegation, and unknown property. Added null-associated-entity test to ToManyEntityMultiTenantFilterBinderSpec. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
# Conflicts: # grails-data-mongodb/core/src/test/groovy/org/apache/grails/data/mongo/core/GrailsDataMongoTckManager.groovy # grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/BeforeUpdatePropertyPersistenceSpec.groovy # grails-datamapping-core-test/src/test/groovy/org/grails/datastore/gorm/CustomAutoTimestampSpec.groovy # grails-datamapping-core-test/src/test/groovy/org/grails/datastore/gorm/NestedCriteriaWithNamedQuerySpec.groovy # grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/GormStaticApi.groovy # grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/query/NamedCriteriaProxy.groovy # grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/NamedQuerySpec.groovy # grails-test-suite-uber/src/test/groovy/grails/compiler/DomainClassWithInnerClassUsingStaticCompilationSpec.groovy
This comment has been minimized.
This comment has been minimized.
…s any hibernate 5 or hibernate 7 project
This comment has been minimized.
This comment has been minimized.
# Conflicts: # grails-data-mongodb/core/src/test/groovy/org/apache/grails/data/mongo/core/GrailsDataMongoTckManager.groovy
This comment has been minimized.
This comment has been minimized.
…correct versions are chosen.
This comment has been minimized.
This comment has been minimized.
🚨 TestLens detected 113 failed tests 🚨Here is what you can do:
Test Summary
🏷️ Commit: a6c3762 Test Failures (first 5 of 119)BookControllerUnitSpec (:grails-test-examples-hibernate7-grails-hibernate:test in CI / Functional Tests (Java 21, indy=false))BookControllerUnitSpec (:grails-test-examples-hibernate7-grails-hibernate:test in CI / Functional Tests (Java 25, indy=false))AggregateMethodSpec (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)AssignedIdentifierSpec (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)AutoRunWithMultipleDataSourceSpec > runs app with a multiple datasource (:grails-data-hibernate7-dbmigration:integrationTest in CI - Groovy Joint Validation Build / build_grails)Muted TestsNote Checks are currently running using the configuration below. Select tests to mute in this pull request: 🔲 AggregateMethodSpec Reuse successful test results: 🔲 ♻️ Only rerun the tests that failed or were muted before Click the checkbox to trigger a rerun: 🔲 Rerun jobs Learn more about TestLens at testlens.app. |
Reopening. This PR replaces #15530