Skip to content

feat: wire Hibernate 7 adapter to GormRegistry O(M+N) scaling#15787

Open
borinquenkid wants to merge 1 commit into
feat/gorm-registry-miscfrom
feat/gorm-registry-hibernate7
Open

feat: wire Hibernate 7 adapter to GormRegistry O(M+N) scaling#15787
borinquenkid wants to merge 1 commit into
feat/gorm-registry-miscfrom
feat/gorm-registry-hibernate7

Conversation

@borinquenkid

Copy link
Copy Markdown
Member

Summary

Wires the Hibernate 7 adapter into the GormRegistry introduced in #15780.

  • HibernateGormApiFactory (H7) — factory that creates HibernateGormStaticApi, HibernateGormInstanceApi, and HibernateGormValidationApi instances typed to the H7 HibernateDatastore
  • HibernateGormEnhancer.registerConstraints() (H7) — registers HibernateGormApiFactory with GormRegistry so Hibernate 7-typed APIs are used for all H7 entities
  • GormAutoTimestampFlushEntityEventListener — new H7 flush listener that respects the registry-based session lifecycle
  • Child datastore initialisation — ensures child HibernateDatastore instances (per-tenant DATABASE mode) are registered with the registry on creation
  • Unit tests: HibernateGormApiFactorySpec, GormRegistryScalabilitySpec, HibernateTenantContextProfilingSpec, HibernateTransactionManagerSpec

Test plan

  • ./gradlew :grails-data-hibernate7:test passes
  • TCK suite passes with -Phibernate7.gorm.suite

Stack

🤖 Generated with Claude Code

@borinquenkid borinquenkid force-pushed the feat/gorm-registry-misc branch from 6f5c31f to 590e21c Compare June 27, 2026 17:37
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-hibernate7 branch from cd01f3d to b9e01f9 Compare June 27, 2026 17:39
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-misc branch from 590e21c to b97eaeb Compare June 27, 2026 18:15
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-hibernate7 branch from b9e01f9 to 43a547a Compare June 27, 2026 18:15
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-misc branch from b97eaeb to 3cc9135 Compare June 27, 2026 20:47
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-hibernate7 branch from 43a547a to f108fca Compare June 27, 2026 20:47
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-misc branch from 3cc9135 to a884511 Compare June 27, 2026 22:04
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-hibernate7 branch from f108fca to 4bbe71e Compare June 27, 2026 22:04
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-misc branch from a884511 to cba09b6 Compare June 27, 2026 22:23
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-hibernate7 branch from 4bbe71e to 54f1e3d Compare June 27, 2026 22:23
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-misc branch from cba09b6 to d663ee9 Compare June 27, 2026 22:59
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-hibernate7 branch from 54f1e3d to 12ea8b0 Compare June 27, 2026 22:59
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-misc branch from d663ee9 to 6d53d02 Compare June 28, 2026 00:19
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-hibernate7 branch from 12ea8b0 to 3d0ff1a Compare June 28, 2026 00:19
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-misc branch from 6d53d02 to edbbbb4 Compare June 28, 2026 00:54
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-hibernate7 branch from 3d0ff1a to af5f9b8 Compare June 28, 2026 00:54
…store init

Wires Hibernate 7 to the new GormRegistry with correct child datastore
initialization order, fixing the gaps that PR #15771 intentionally deferred:

- HibernateDatastore (H7): registers child datastores with GormRegistry eagerly
  during initialization, preserving schema/database/datasource routing
- HibernateGormInstanceApi: use getHibernateTemplate() lazy getter for
  isAttached(), lock(), and attach() — factory constructor leaves the field null
- HibernateGormStaticApi: executeQuery(query, Map) passes params as both named
  params and query settings so max/offset pagination is applied
- HibernateSession: coerceId() converts String IDs to the entity's declared
  identifier type in retrieveAll(), fixing String→Long lookup mismatch
- HibernateGormEnhancerSpec: updated to use GormRegistry public API
- HibernateDirtyCheckingSpec / HibernateUpdateFromListenerSpec: local Person
  renamed to DirtyCheckPerson to avoid DuplicateMappingException with TCK
- grails-test-examples/hibernate7: demo33 UniqueConstraintOnHasOneSpec
  @NotYetImplemented removed (test now passes); GormAdvancedSpec pagination fixed
- grails-data-hibernate7-core GormApiAllocationSpec: verifies O(M+N) API count
  across single-datasource, multi-datasource, and multi-tenant configurations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-misc branch from edbbbb4 to 54d8eaa Compare June 28, 2026 01:36
@borinquenkid borinquenkid force-pushed the feat/gorm-registry-hibernate7 branch from af5f9b8 to cde33f4 Compare June 28, 2026 01:36
@testlens-app

testlens-app Bot commented Jun 28, 2026

Copy link
Copy Markdown

🚨 TestLens detected 40 failed tests 🚨

Here is what you can do:

  1. Inspect the test failures carefully.
  2. If you are convinced that some of the tests are flaky, you can mute them below.
  3. Finally, trigger a rerun by checking the rerun checkbox.

Test Summary

CI / Build Grails-Core (macos-latest, 21) > :grails-data-graphql-core:test

Test Runs
CreateEntityDataFetcherSpec > test get
DeleteEntityDataFetcherSpec > test get
DeleteEntityDataFetcherSpec > test get invalid
EntityDataFetcherSpec
SingleEntityDataFetcherSpec
SoftDeleteEntityDataFetcherSpec
UpdateEntityDataFetcherSpec > test get
UpdateEntityDataFetcherSpec > test optimistic locking
UpdateEntityDataFetcherSpec > test optimistic locking with null version

CI / Build Grails-Core (ubuntu-latest, 21) > :grails-data-graphql-core:test

Test Runs
CreateEntityDataFetcherSpec > test get
DeleteEntityDataFetcherSpec > test get
DeleteEntityDataFetcherSpec > test get invalid
EntityDataFetcherSpec
SingleEntityDataFetcherSpec
SoftDeleteEntityDataFetcherSpec
UpdateEntityDataFetcherSpec > test get
UpdateEntityDataFetcherSpec > test optimistic locking
UpdateEntityDataFetcherSpec > test optimistic locking with null version

CI / Build Grails-Core (ubuntu-latest, 21) > :grails-data-simple:test

Test Runs
SimpleMapQuerySpec > test query isolation in DISCRIMINATOR mode

CI / Build Grails-Core (ubuntu-latest, 25) > :grails-data-graphql-core:test

Test Runs
CreateEntityDataFetcherSpec > test get
DeleteEntityDataFetcherSpec > test get
DeleteEntityDataFetcherSpec > test get invalid
EntityDataFetcherSpec
SingleEntityDataFetcherSpec
SoftDeleteEntityDataFetcherSpec
UpdateEntityDataFetcherSpec > test get
UpdateEntityDataFetcherSpec > test optimistic locking
UpdateEntityDataFetcherSpec > test optimistic locking with null version

CI / Build Grails-Core (ubuntu-latest, 25) > :grails-data-simple:test

Test Runs
SimpleMapQuerySpec > test query isolation in DISCRIMINATOR mode

CI / Build Grails-Core (ubuntu-latest, 25) > :grails-datamapping-core:test

Test Runs
GormEnhancerAllQualifiersSpec > registerEntity can resolve through injected registry without touching global singleton
GormEntityTransformSpec > test property/method missing

CI / Build Grails-Core Rerunning all Tasks (ubuntu-latest, 21) > :grails-data-graphql-core:test

Test Runs
CreateEntityDataFetcherSpec > test get
DeleteEntityDataFetcherSpec > test get
DeleteEntityDataFetcherSpec > test get invalid
EntityDataFetcherSpec
SingleEntityDataFetcherSpec
SoftDeleteEntityDataFetcherSpec
UpdateEntityDataFetcherSpec > test get
UpdateEntityDataFetcherSpec > test optimistic locking
UpdateEntityDataFetcherSpec > test optimistic locking with null version

🏷️ Commit: cde33f4
▶️ Tests: 6520 executed
⚪️ Checks: 41/41 completed

Test Failures (first 10 of 40)

CreateEntityDataFetcherSpec > test get (:grails-data-graphql-core:test in CI / Build Grails-Core (macos-latest, 21))
java.lang.NullPointerException: Cannot invoke "org.grails.datastore.mapping.services.ServiceRegistry.getService(java.lang.Class)" because "datastore" is null
	at org.grails.gorm.graphql.fetcher.DefaultGormDataFetcher.withTransaction(DefaultGormDataFetcher.groovy:135)
	at org.grails.gorm.graphql.fetcher.impl.CreateEntityDataFetcher.get(CreateEntityDataFetcher.groovy:46)
	at org.grails.gorm.graphql.fetcher.impl.CreateEntityDataFetcherSpec.test get(CreateEntityDataFetcherSpec.groovy:42)
DeleteEntityDataFetcherSpec > test get (:grails-data-graphql-core:test in CI / Build Grails-Core (macos-latest, 21))
java.lang.NullPointerException: Cannot invoke "org.grails.orm.hibernate.AbstractHibernateDatastore.getConnectionSources()" because the return value of "groovy.lang.Reference.get()" is null
	at org.grails.orm.hibernate.AbstractHibernateGormStaticApi.withNewSession(AbstractHibernateGormStaticApi.groovy:118)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewSession(GormEntity.groovy:1140)
	at org.grails.gorm.graphql.fetcher.impl.DeleteEntityDataFetcherSpec.test get(DeleteEntityDataFetcherSpec.groovy:53)
DeleteEntityDataFetcherSpec > test get invalid (:grails-data-graphql-core:test in CI / Build Grails-Core (macos-latest, 21))
Too few invocations for:

1 * getArgument('id') >> 95   (0 invocations)

Unmatched invocations (ordered by similarity):

None

Too few invocations for:

1 * getMergedField()   (0 invocations)

Unmatched invocations (ordered by similarity):

None


	at org.spockframework.mock.runtime.InteractionScope.verifyInteractions(InteractionScope.java:110)
	at org.spockframework.mock.runtime.MockController.leaveScope(MockController.java:95)
	at org.grails.gorm.graphql.fetcher.impl.DeleteEntityDataFetcherSpec.test get invalid(DeleteEntityDataFetcherSpec.groovy:74)
EntityDataFetcherSpec (:grails-data-graphql-core:test in CI / Build Grails-Core (macos-latest, 21))
java.lang.IllegalStateException: No PlatformTransactionManager set
	at org.springframework.util.Assert.state(Assert.java:80)
	at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:128)
	at grails.gorm.transactions.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:115)
	at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:687)
	at org.grails.datastore.gorm.GormStaticApi.withNewTransaction(GormStaticApi.groovy:649)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewTransaction(GormEntity.groovy:1063)
	at org.grails.gorm.graphql.fetcher.impl.EntityDataFetcherSpec.setupSpec(EntityDataFetcherSpec.groovy:32)
SingleEntityDataFetcherSpec (:grails-data-graphql-core:test in CI / Build Grails-Core (macos-latest, 21))
java.lang.IllegalStateException: No PlatformTransactionManager set
	at org.springframework.util.Assert.state(Assert.java:80)
	at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:128)
	at grails.gorm.transactions.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:115)
	at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:687)
	at org.grails.datastore.gorm.GormStaticApi.withNewTransaction(GormStaticApi.groovy:649)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewTransaction(GormEntity.groovy:1063)
	at org.grails.gorm.graphql.fetcher.impl.SingleEntityDataFetcherSpec.setupSpec(SingleEntityDataFetcherSpec.groovy:35)
SoftDeleteEntityDataFetcherSpec (:grails-data-graphql-core:test in CI / Build Grails-Core (macos-latest, 21))
java.lang.IllegalStateException: No PlatformTransactionManager set
	at org.springframework.util.Assert.state(Assert.java:80)
	at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:128)
	at grails.gorm.transactions.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:115)
	at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:687)
	at org.grails.datastore.gorm.GormStaticApi.withNewTransaction(GormStaticApi.groovy:649)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewTransaction(GormEntity.groovy:1063)
	at org.grails.gorm.graphql.fetcher.impl.SoftDeleteEntityDataFetcherSpec.setupSpec(SoftDeleteEntityDataFetcherSpec.groovy:36)
UpdateEntityDataFetcherSpec > test get (:grails-data-graphql-core:test in CI / Build Grails-Core (macos-latest, 21))
java.lang.NullPointerException: Cannot invoke "org.grails.datastore.mapping.services.ServiceRegistry.getService(java.lang.Class)" because "datastore" is null
	at org.grails.gorm.graphql.fetcher.DefaultGormDataFetcher.withTransaction(DefaultGormDataFetcher.groovy:135)
	at org.grails.gorm.graphql.fetcher.impl.UpdateEntityDataFetcher.get(UpdateEntityDataFetcher.groovy:48)
	at org.grails.gorm.graphql.fetcher.impl.UpdateEntityDataFetcherSpec.test get(UpdateEntityDataFetcherSpec.groovy:48)
UpdateEntityDataFetcherSpec > test optimistic locking (:grails-data-graphql-core:test in CI / Build Grails-Core (macos-latest, 21))
java.lang.NullPointerException: Cannot invoke "org.grails.datastore.mapping.services.ServiceRegistry.getService(java.lang.Class)" because "datastore" is null
	at org.grails.gorm.graphql.fetcher.DefaultGormDataFetcher.withTransaction(DefaultGormDataFetcher.groovy:135)
	at org.grails.gorm.graphql.fetcher.impl.UpdateEntityDataFetcher.get(UpdateEntityDataFetcher.groovy:48)
	at org.grails.gorm.graphql.fetcher.impl.UpdateEntityDataFetcherSpec.test optimistic locking(UpdateEntityDataFetcherSpec.groovy:69)
UpdateEntityDataFetcherSpec > test optimistic locking with null version (:grails-data-graphql-core:test in CI / Build Grails-Core (macos-latest, 21))
java.lang.NullPointerException: Cannot invoke "org.grails.datastore.mapping.services.ServiceRegistry.getService(java.lang.Class)" because "datastore" is null
	at org.grails.gorm.graphql.fetcher.DefaultGormDataFetcher.withTransaction(DefaultGormDataFetcher.groovy:135)
	at org.grails.gorm.graphql.fetcher.impl.UpdateEntityDataFetcher.get(UpdateEntityDataFetcher.groovy:48)
	at org.grails.gorm.graphql.fetcher.impl.UpdateEntityDataFetcherSpec.test optimistic locking with null version(UpdateEntityDataFetcherSpec.groovy:88)
CreateEntityDataFetcherSpec > test get (:grails-data-graphql-core:test in CI / Build Grails-Core (ubuntu-latest, 21))
java.lang.NullPointerException: Cannot invoke "org.grails.datastore.mapping.services.ServiceRegistry.getService(java.lang.Class)" because "datastore" is null
	at org.grails.gorm.graphql.fetcher.DefaultGormDataFetcher.withTransaction(DefaultGormDataFetcher.groovy:135)
	at org.grails.gorm.graphql.fetcher.impl.CreateEntityDataFetcher.get(CreateEntityDataFetcher.groovy:46)
	at org.grails.gorm.graphql.fetcher.impl.CreateEntityDataFetcherSpec.test get(CreateEntityDataFetcherSpec.groovy:42)

Muted Tests (first 20 of 40)

Select tests to mute in this pull request:

  • CreateEntityDataFetcherSpec > test get
  • DeleteEntityDataFetcherSpec > test get
  • DeleteEntityDataFetcherSpec > test get invalid
  • EntityDataFetcherSpec
  • GormEnhancerAllQualifiersSpec > registerEntity can resolve through injected registry without touching global singleton
  • GormEntityTransformSpec > test property/method missing
  • SimpleMapQuerySpec > test query isolation in DISCRIMINATOR mode
  • SingleEntityDataFetcherSpec
  • SoftDeleteEntityDataFetcherSpec
  • UpdateEntityDataFetcherSpec > test get
  • UpdateEntityDataFetcherSpec > test optimistic locking
  • UpdateEntityDataFetcherSpec > test optimistic locking with null version

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant