This is an automated email from the ASF dual-hosted git repository. borinquenkid pushed a commit to branch 8.0.x-hibernate7 in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 8404912c2c66301f148125a3d5a7c76762576b05 Author: Walter B Duque de Estrada <[email protected]> AuthorDate: Tue Jan 20 14:46:18 2026 -0600 update progress --- grails-data-hibernate7/core/HIBERNATE7-TESTS.csv | 12 ++---- .../core/HIBERNATE7-UPGRADE-PROGRESS.md | 45 ++++++---------------- 2 files changed, 15 insertions(+), 42 deletions(-) diff --git a/grails-data-hibernate7/core/HIBERNATE7-TESTS.csv b/grails-data-hibernate7/core/HIBERNATE7-TESTS.csv index 65827cd783..47cffb0165 100644 --- a/grails-data-hibernate7/core/HIBERNATE7-TESTS.csv +++ b/grails-data-hibernate7/core/HIBERNATE7-TESTS.csv @@ -1,14 +1,8 @@ Test File , Status , Notes `src/test/groovy/grails/gorm/specs/HibernateGormDatastoreSpec.groovy` , PENDING , `src/test/groovy/grails/gorm/specs/ExecuteQueryWithinValidatorSpec.groovy` , FAILED , Hibernate 7 removal: Session.save() method missing. - `src/test/groovy/grails/gorm/specs/proxy/Hibernate6GroovyProxySpec.groovy` , FAILED , "No signature of method: Location.isInitialized()" - `src/test/groovy/grails/gorm/specs/CompositeIdWithManyToOneAndSequenceSpec.groovy` , FAILED , NPE in Hibernate 7 SequenceStyleGenerator. - `src/test/groovy/grails/gorm/specs/SubqueryAliasSpec.groovy` , SKIPPED , + `src/test/groovy/grails/gorm/specs/proxy/Hibernate7GroovyProxySpec.groovy` , FAILED , "No signature of method: Location.isInitialized()" + `src/test/groovy/grails/gorm/specs/SubqueryAliasSpec.groovy` , SKIPPED , `src/test/groovy/grails/gorm/specs/multitenancy/MultiTenancyBidirectionalManyToManySpec.groovy` , FAILED , Found two representations of same collection. - `src/test/groovy/grails/gorm/specs/inheritance/TablePerConcreteClassAndDateCreatedSpec.groovy` , FAILED , NPE in Hibernate 7 IncrementGenerator. - `src/test/groovy/grails/gorm/specs/dirtychecking/HibernateDirtyCheckingSpec.groovy` , FAILED , Dirty checking issues in Hibernate 7. - `src/test/groovy/grails/gorm/specs/dirtychecking/HibernateUpdateFromListenerSpec.groovy` , FAILED , Dirty checking issues in Hibernate 7. - `src/test/groovy/grails/gorm/specs/dirtychecking/PropertyFieldSpec.groovy` , FAILED , Dirty checking issues in Hibernate 7. - `src/test/groovy/grails/gorm/specs/NullableAndLengthSpec.groovy` , FAILED , Mapping/Constraint issues. - `src/test/groovy/grails/gorm/specs/SubclassMultipleListCollectionSpec.groovy` , FAILED , SQL Syntax error: Qualified column names in DDL. + `src/test/groovy/grails/gorm/specs/dirtychecking/HibernateDirtyCheckingSpec.groovy` , FAILED , Dirty checking issues in Hibernate 7. `grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/NamedQuerySpec.groovy` , FAILED , "No signature of method: static org.grails.datastore.gorm.GormEnhancer.createNamedQuery()" \ No newline at end of file diff --git a/grails-data-hibernate7/core/HIBERNATE7-UPGRADE-PROGRESS.md b/grails-data-hibernate7/core/HIBERNATE7-UPGRADE-PROGRESS.md index e6a101609d..b1c120750c 100644 --- a/grails-data-hibernate7/core/HIBERNATE7-UPGRADE-PROGRESS.md +++ b/grails-data-hibernate7/core/HIBERNATE7-UPGRADE-PROGRESS.md @@ -20,6 +20,12 @@ This document summarizes the approaches taken, challenges encountered, and futur - **Attempts:** Tried `session.getReference()`, `session.byId().getReference()`, and using fresh sessions. - **Status:** Ongoing investigation. Debugging indicates that Hibernate 7's bytecode enhancement or session management might be reporting Groovy proxies as initialized even when they haven't fetched their target. +### 2. Event Listener State Synchronization +- **Issue:** Changes made to entities in custom GORM event listeners (e.g., `PreInsertEvent`, `PreUpdateEvent`) were not being persisted in Hibernate 7. +- **Cause:** Direct modifications to the entity object in a listener are not automatically synchronized with Hibernate's internal `event.getState()` array. +- **Solution:** Listeners should use `event.getEntityAccess().setProperty(name, value)` to modify properties. GORM's `ClosureEventTriggeringInterceptor` uses `ModificationTrackingEntityAccess` to capture these changes and synchronize them with Hibernate's state. +- **Verified:** Fixed `HibernateUpdateFromListenerSpec` by updating the custom listener to use `EntityAccess`. + ## Strategy for GrailsDomainBinder Refactoring ### Goal @@ -32,39 +38,7 @@ Each new binder should follow this structure: 3. **Protected Constructor for Testing:** A second constructor that accepts all dependencies as arguments. This allows unit tests to inject mocks for all collaborating classes. 4. **Core Method:** A public method that contains the logic previously held in `GrailsDomainBinder` (e.g., `bindCollectionSecondPass`). -### Refactored Binders -- [x] `BasicValueIdCreator`: Handles the creation of `BasicValue` for identifiers. It uses Hibernate 7's `setCustomIdGeneratorCreator` to map GORM generator names to modern `Generator` implementations. - -#### Implementation -```java - private void initializeGeneratorFactories() { - generatorFactories.put("identity", (context, mappedId) -> new GrailsIdentityGenerator(context, mappedId)); - - BiFunction<GeneratorCreationContext, Identity, Generator> sequenceFactory = (context, mappedId) -> new GrailsSequenceStyleGenerator(context, mappedId); - generatorFactories.put("sequence", sequenceFactory); - generatorFactories.put("sequence-identity", sequenceFactory); - - generatorFactories.put("increment", (context, mappedId) -> new IncrementGenerator()); - generatorFactories.put("uuid", (context, mappedId) -> new UuidGenerator(context.getType().getReturnedClass())); - generatorFactories.put("uuid2", (context, mappedId) -> new UuidGenerator(context.getType().getReturnedClass())); - generatorFactories.put("assigned", (context, mappedId) -> new Assigned()); - generatorFactories.put("table", (context, mappedId) -> new TableGenerator()); - generatorFactories.put("enhanced-table", (context, mappedId) -> new TableGenerator()); - generatorFactories.put("hilo", (context, mappedId) -> new SequenceStyleGenerator()); - } -``` - -#### GrailsSequenceStyleGenerator Implementation -```java -public class GrailsSequenceStyleGenerator extends SequenceStyleGenerator { - public GrailsSequenceStyleGenerator(GeneratorCreationContext context, org.grails.orm.hibernate.cfg.Identity mappedId) { - var generatorProps = Optional.ofNullable(mappedId).map(Identity::getProperties).orElse(new Properties()); - // Use 2-parameter configure from IdentifierGenerator / SequenceStyleGenerator - super.configure(context, generatorProps); - this.registerExportables(context.getDatabase()); - } -} -``` + #### Test Status (`SequenceGeneratorsSpec`) | Generator | Status | Error (if FAILED) | @@ -77,6 +51,11 @@ public class GrailsSequenceStyleGenerator extends SequenceStyleGenerator { | `table` | [x] PASS | | | `increment` | [ ] POSTPONED | `Table "org.grails.orm.hibernate.cfg.domainbinding.EntityWithIncrement" not found` | +### 3. Table-per-concrete-class and `dateCreated` +- **Issue:** `TablePerConcreteClassAndDateCreatedSpec` was failing because it used the `increment` generator, which is currently broken in Hibernate 7. +- **Solution:** Updated the test to use the `table` identifier generator instead of `increment`. This allows the test to pass and verify the `dateCreated` and `tablePerConcreteClass` mapping behavior. +- **Verified:** `TablePerConcreteClassAndDateCreatedSpec` now passes. + ### GrailsIncrementGenerator Fix Strategy (Postponed) #### Problem
