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 5e717b8669509a2146ade71037550565908d9a13 Author: Walter B Duque de Estrada <[email protected]> AuthorDate: Tue Jan 13 16:43:27 2026 -0600 update progress --- .../core/HIBERNATE7-UPGRADE-PROGRESS.md | 66 ++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/grails-data-hibernate7/core/HIBERNATE7-UPGRADE-PROGRESS.md b/grails-data-hibernate7/core/HIBERNATE7-UPGRADE-PROGRESS.md new file mode 100644 index 0000000000..2690e228b6 --- /dev/null +++ b/grails-data-hibernate7/core/HIBERNATE7-UPGRADE-PROGRESS.md @@ -0,0 +1,66 @@ +# Hibernate 7 Migration Progress Report - GORM Core + +## Overview +This document summarizes the approaches taken, challenges encountered, and future steps for upgrading the GORM Hibernate implementation to Hibernate 7. + +## Completed Tasks & Approaches + +### 1. Cascade Logic Refactoring +- **Approach:** Centralized cascade check logic by moving `isSaveUpdateCascade` from `GrailsDomainBinder` to the `CascadeBehavior` enum. +- **Hibernate 7 Compatibility:** Mapped the legacy `save-update` cascade style to `persist,merge`, as Hibernate 7 removed direct support for `save-update`. +- **Result:** Successfully refactored and added unit tests in `CascadeBehaviorEnumSpec`. + +### 2. Naming Strategy Compatibility +- **Approach:** Updated `DefaultColumnNameFetcher` to replace package dots with underscores in Fully Qualified Class Name (FQCN) prefixes. +- **Reasoning:** Hibernate 7's default naming strategies preserve dots in class names, which can lead to invalid SQL or unexpected column names in join tables. GORM expects underscores for compatibility. +- **Result:** Resolved failures in `DefaultColumnNameFetcherSpec`. + +### 3. Column Binding Fixes +- **Approach:** Refined `ColumnBinder` to only apply conventional naming to associations if the column name is `null`. +- **Testing:** Updated `ColumnBinderSpec` to use name-less `Column` instances (`new Column()`) for association tests, ensuring conventional naming is correctly applied without interfering with explicit mappings. +- **Result:** All 14 tests in `ColumnBinderSpec` are passing. + +### 4. AST Transformation for `ManagedEntity` +- **Approach:** Updated `HibernateEntityTransformation` to implement the new methods required by the Hibernate 7 `ManagedEntity` interface. +- **Implementation:** Added `$$_hibernate_instanceId` field and implemented `$$_hibernate_getInstanceId()` and `$$_hibernate_setInstanceId(int)`. +- **Result:** Resolved compilation errors in `HibernateEntityTransformationSpec`. + +### 5. API Updates in Tests +- **Approach:** Replaced removed Hibernate 6 methods with their Hibernate 7 equivalents in test specifications. +- **Changes:** Swapped `session.save()` for `session.persist()` in `ExecuteQueryWithinValidatorSpec`. +- **Result:** `ExecuteQueryWithinValidatorSpec` is now passing. + +### 6. Encapsulation of Save Logic +- **Observation:** `HibernateGormInstanceApi` correctly encapsulates `save()` calls by delegating to `performPersist()` (using `session.persist()`) if the entity is new (ID is null), or `performMerge()` (using `session.merge()`) if it already exists. +- **Hibernate 7 Compatibility:** This centralizes the handling of Hibernate 7's removal of `session.save()`. +- **Requirement:** Direct `session.save()` calls in the codebase or TCK must be identified and replaced with `persist()` or `merge()` as appropriate. +- **Audit Results:** + - `GrailsHibernateTemplate.save(Object)` was updated to use `session.persist(Object)`. + - `ExecuteQueryWithinValidatorSpec.groovy` direct call replaced with `persist()`. + - No other direct `session.save()` calls found in `src/main` or `src/test` of the `core` module. + - Systematic audit of other modules and TCK is still required. + +## Challenges & Failures + +### 1. Proxy Initialization Behavior +- **Issue:** In `Hibernate6GroovyProxySpec`, `Location.proxy(id)` returns an object that is already initialized (`Hibernate.isInitialized(location) == true`), even after clearing the session. +- **Attempts:** Tried `session.getReference()`, `session.byId().getReference()`, and using fresh sessions. +- **Status:** Ongoing investigation. Debugging indicates that even native Hibernate proxies might be reporting as initialized or are being initialized during the proxy creation/retrieval process in the test environment. + +### 2. SQL Syntax Errors in DDL +- **Issue:** Several tests (e.g., `CascadeBehaviorPersisterSpec`) show `JdbcSQLSyntaxErrorException` during schema creation. +- **Observation:** DDL statements are attempting to use qualified class names as column names (e.g., `create table ... (org.grails.orm..._id bigint)`), which fails in H2. This is likely related to how Hibernate 7 handles component or join column naming when dots are present. + +### 3. Missing Methods in Proxies +- **Issue:** Hibernate 7 proxies no longer implement `isInitialized()` or `getInitialized()` directly on the proxy object. +- **Solution:** Switched to `Hibernate.isInitialized(proxy)`. + +## Future Steps + +1. **Resolve Proxy Initialization:** Determine why proxies are returning as initialized in `Hibernate6GroovyProxySpec`. Investigate if Hibernate 7's bytecode enhancement or ByteBuddy factory settings are interfering. +2. **Fix DDL Generation:** Investigate why FQCNs are leaking into DDL column definitions. This likely requires further changes in `ColumnNameFetcher` or the mapping binders to ensure dots are replaced by underscores globally for generated columns. +3. **Continue TCK Failure Audit:** Move to the next items in `HIBERNATE7-TESTS.csv`: + - `HibernateGormDatastoreSpec` (Pending) + - `TwoUnidirectionalHasManySpec` (DDL issues) + - `CompositeIdWithManyToOneAndSequenceSpec` (NPE in SequenceStyleGenerator) +4. **Address `Session.save()` usage:** Systematically find and replace `save()` with `persist()` or `merge()` across the codebase and TCK where direct Hibernate session access is used.
