borinquenkid opened a new pull request, #15678: URL: https://github.com/apache/grails-core/pull/15678
## Description This PR replaces #15656, which was rebuilt on a clean branch to remove a corruption commit from the history. **Problem:** In multi-tenant GORM environments with many tenants (M) and domain classes (N), the previous implementation instantiated a full set of static API, instance API, and validation API objects per tenant per entity, producing O(M × N) object allocations. This caused excessive memory consumption and degraded startup performance as tenant counts scaled. **Solution:** Refactor `GormRegistry` to use a single shared registry keyed by entity class name and qualifier (datasource/tenant), with the GORM API objects created once per entity per qualifier and reused across tenants. This reduces the allocation profile to O(M + N). **This rebuild also fixes two regression classes exposed by the new registry:** 1. **Multi-tenancy resolution regressions** — `GormApiResolver` and `GormRegistry.registerEntityDatastores` were routing DISCRIMINATOR/SCHEMA tenant IDs through the datasource connection lookup path, causing child datastores to be overwritten by the parent and `PartitionedMultiTenancySpec.count()` to NPE. Fixed by detecting multi-tenancy mode before delegating to `getDatastoreForConnection`, and by skipping non-DEFAULT qualifier registration when the qualifier resolves back to the parent (i.e., it's a runtime tenant ID, not a datasource name). 2. **Child datastore initialization order** — `HibernateDatastore` (H5) and `ChildHibernateDatastore` (H7) were throwing `ConfigurationException` when `getDatastoreForConnection` was called for a sibling during initialization before all children were registered. Fixed to return `null` during the initialization phase so `GormRegistry` falls back gracefully and re-registers once initialization completes. **Test infrastructure:** Added `forkEvery = 1` to `gradle/hibernate5-test-config.gradle` and `gradle/hibernate7-test-config.gradle`. The root config uses `forkEvery = 50/100` for speed, but with a shared `GormRegistry` singleton, TCK specs running in the same JVM before `PartitionedMultiTenancySpec` were clearing `datastoresByQualifier["default"]` and causing the NPE described above. Each test class now gets its own JVM. **Verified:** H5 — 669 tests / 0 failures. H7 — 2960 tests / 0 failures. ## Contributor Checklist ### Issue and Scope - [x] This PR is linked to an existing issue that has been **acknowledged or approved** by the project team. *(Replaces #15656, which tracks the approved O(M+N) scaling work.)* - [x] This PR addresses the **complete scope** of the linked issue. - [x] This PR contains a **single, focused change**. - [x] This PR targets the **correct branch** (`8.0.x-hibernate7` — major release branch; breaking API changes permitted). ### Code Quality - [x] I have **added or updated tests** that cover the changes introduced in this PR. - [x] I have verified that all existing tests pass (H5: 669/0 failures, H7: 2960/0 failures). - [x] My code follows the project's **code style** guidelines. `./gradlew codeStyle` has been run and violations resolved. - [x] This PR does **not** include unsolicited reformatting or unrelated refactoring. - [x] Generative AI tooling was used in preparing this contribution with a quality model, consistent with the project's quality standards. ### Licensing and Attribution - [x] All contributed code is provided under the Apache License 2.0, and new source files include the appropriate Apache license header. - [x] I have the necessary rights to submit this contribution and confirm it is my own original work. - [x] Generative AI tooling use follows the [ASF policy on generative tooling](https://www.apache.org/legal/generative-tooling.html) and is properly attributed. ### Documentation - [x] No new user-facing APIs are introduced; this is a performance/correctness fix to the internal registry. - [x] The PR description explains what was changed and why. -- 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]
