jamesfredley commented on PR #15561:
URL: https://github.com/apache/grails-core/pull/15561#issuecomment-4200976102
## Hibernate 5 vs 7 - Detailed Differences and Test Coverage
### GORM API differences between Hibernate 5.6 and 7.2
Investigation of the functional test suite revealed these concrete
behavioral differences between the two Hibernate versions:
#### 1. `executeUpdate(String)` no longer accepts plain Strings (H7)
H7's `HibernateGormStaticApi` rejects `executeUpdate('delete from Foo')`
with a plain String. It requires either a GString with interpolated parameters
or the parameterized overload:
```groovy
// H5 - works
Book.executeUpdate('delete from Book')
// H7 - throws UnsupportedOperationException
Book.executeUpdate('delete from Book')
// H7 - correct
Book.executeUpdate('delete from Book', [:])
```
Error: `UnsupportedOperationException: executeUpdate(CharSequence) only
accepts a Groovy GString with interpolated parameters`
This was already fixed in the h7-labeled copies (e.g.,
`DataServiceMultiDataSourceSpec`, `MetricService`), where
`executeUpdate('delete from Foo')` was changed to `executeUpdate('delete from
Foo', [:])`.
#### 2. `HibernateSpec` domain class detection (H7)
H5's `HibernateSpec` auto-detects domain classes via classpath scanning.
H7's `HibernateSpec` was rewritten to use `HibernateDatastoreSpringInitializer`
with a different domain class discovery mechanism. Some tests need an explicit
`getDomainClasses()` override:
```groovy
// H5 - auto-detects Book from classpath
class BookHibernateSpec extends HibernateSpec { ... }
// H7 - needs explicit declaration in some cases
class BookHibernateSpec extends HibernateSpec {
@Override
List<Class> getDomainClasses() { [Book] }
}
```
#### 3. `ChainedTransactionManager` commit behavior (H7)
H7 changed how `ChainedTransactionManager.commit()` handles multi-datasource
transactions, throwing `HeuristicCompletionException: outcome state is rolled
back` where H5 committed successfully. The h7-labeled `datasources` tests use
`session.doReturningWork { it.metaData.getURL() }` instead of
`session.connection().metaData.getURL()`.
#### 4. `@RestoreSystemProperties` vs explicit cleanup (H7)
H7 tests replaced Spock's `@RestoreSystemProperties` annotation with
explicit `cleanup()` methods for system property management (seen in
`DatabasePerTenantSpec`, `MultiTenantMultiDataSourceSpec`).
#### 5. `@Integration` annotation (H7)
Some H7 integration tests require `@Integration(applicationClass =
Application)` explicitly, where H5 inferred the application class automatically.
#### 6. `HttpClientSupport` trait vs explicit `HttpClient` (H7)
H7 tests replaced `implements HttpClientSupport` with explicit `@Shared
HttpClient client` + `@OnceBefore` setup (seen in
`MultiDataSourceWithSessionSpec`, `BookControllerSpec` in issue450).
#### 7. JSON response structure differences (H7)
Views/JSON rendering produces slightly different output with H7 -
association rendering and HAL responses differ.
#### 8. Scaffolding rendering (H7)
Scaffolding with `grails-fields` renders pages differently under H7, causing
Geb page object assertions to fail.
---
### Test matrix - what runs where
**33 general functional test projects** exist. With `-PhibernateVersion=7`,
dependency substitution swaps `grails-data-hibernate5` to
`grails-data-hibernate7` centrally - no individual build.gradle changes needed.
**5 projects are excluded** from the H7 dep-substitution run because they
exercise H5-specific GORM APIs listed above:
| Project | Failure Category | H7 Equivalent |
|---------|-----------------|---------------|
| `app1` | `HibernateSpec` domain class detection (#2) | No direct
equivalent (unit test only) |
| `datasources` | `ChainedTransactionManager` behavior (#3) | No direct
equivalent (new test project) |
| `gorm` | `executeUpdate(String)` (#1), `@RestoreSystemProperties` (#4),
transaction propagation | H7 labeled copies cover most scenarios |
| `views-functional-tests` | JSON/HAL response structure (#7) | No direct
equivalent |
| `scaffolding-fields` | Scaffolding rendering (#8) | No direct equivalent |
**28 general projects run under both H5 and H7** via the matrix:
`app2`, `app3`, `app4`, `app5`, `async-events-pubsub-demo`, `cache`,
`database-cleanup`, `demo33`, `exploded`, `external-configuration`, `geb`,
`geb-gebconfig`, `gsp-layout`, `gsp-sitemesh3`, `gsp-spring-boot`,
`hyphenated`, `issue-11102`, `issue-11767`, `issue-15228`,
`issue-698-domain-save-npe`, `issue-views-182`, `micronaut`,
`micronaut-groovy-only`, `namespaces`, `plugins`, `scaffolding`, `test-phases`,
`views-functional-tests-plugin`
**12 h5-labeled projects** run only in the H5 slot (as before):
`grails-data-service`, `grails-data-service-multi-datasource`,
`grails-database-per-tenant`, `grails-hibernate`,
`grails-hibernate-groovy-proxy`, `grails-multiple-datasources`,
`grails-multitenant-multi-datasource`, `grails-partitioned-multi-tenancy`,
`grails-schema-per-tenant`, `issue450`, `spring-boot-hibernate`,
`standalone-hibernate`
**12 h7-labeled projects** run only in the H7 slot (as before):
Same 12 projects mirrored in `grails-test-examples/hibernate7/` with the API
adaptations described above.
---
### Also fixed: H7 boot-plugin `AutoConfiguration.imports` was empty
The file `grails-data-hibernate7/boot-plugin/.../AutoConfiguration.imports`
was empty - Spring Boot never discovered `HibernateGormAutoConfiguration` when
H7 was on the classpath. This is a bug independent of the CI matrix work; it
affects any Spring Boot application using `grails-data-hibernate7` via
autoconfiguration. Fixed in commit e2336d9.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]