You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by bo...@apache.org on 2026/06/27 16:35:37 UTC
(grails-core) 06/07: fix: register HibernateGormApiFactory in registerConstraints; update affected tests
This is an automated email from the ASF dual-hosted git repository.
borinquenkid pushed a commit to branch feat/gorm-registry-core-impl
in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 7de58bbf71653e8434af7c739157969bf9faa794
Author: Walter Duque de Estrada <wb...@mac.com>
AuthorDate: Sat Jun 27 10:43:59 2026 -0500
fix: register HibernateGormApiFactory in registerConstraints; update affected tests
Co-Authored-By: Claude Sonnet 4.6 <no...@anthropic.com>
---
.../manager/GraphQLDataFetcherManagerSpec.groovy | 5 +-
.../orm/hibernate/HibernateGormApiFactory.groovy | 73 ++++++++++++++++++++++
.../orm/hibernate/HibernateGormEnhancer.groovy | 5 +-
.../core/GrailsDataHibernate5TckManager.groovy | 19 +++---
.../datastore/gorm/GormEnhancerCleanupSpec.groovy | 61 ++++++------------
.../orm/hibernate/HibernateGormApiFactory.groovy | 73 ++++++++++++++++++++++
.../orm/hibernate/HibernateGormEnhancer.groovy | 4 +-
.../datastore/gorm/GormEnhancerCleanupSpec.groovy | 63 ++++++-------------
.../hibernate/HibernateGormInstanceApiSpec.groovy | 10 +--
.../hibernate/HibernateGormStaticApiSpec.groovy | 3 +-
.../HibernateGormValidationApiSpec.groovy | 5 +-
.../hibernate/SchemaTenantGormEnhancerSpec.groovy | 2 -
.../GrailsIdentityGeneratorSpec.groovy | 5 ++
.../testing/tck/base/GrailsDataTckManager.groovy | 14 +++--
14 files changed, 226 insertions(+), 116 deletions(-)
diff --git a/grails-data-graphql/core/src/test/groovy/org/grails/gorm/graphql/fetcher/manager/GraphQLDataFetcherManagerSpec.groovy b/grails-data-graphql/core/src/test/groovy/org/grails/gorm/graphql/fetcher/manager/GraphQLDataFetcherManagerSpec.groovy
index 0031474e1d..9ff4b35d73 100644
--- a/grails-data-graphql/core/src/test/groovy/org/grails/gorm/graphql/fetcher/manager/GraphQLDataFetcherManagerSpec.groovy
+++ b/grails-data-graphql/core/src/test/groovy/org/grails/gorm/graphql/fetcher/manager/GraphQLDataFetcherManagerSpec.groovy
@@ -20,9 +20,8 @@
package org.grails.gorm.graphql.fetcher.manager
import graphql.schema.DataFetchingEnvironment
-import org.grails.datastore.gorm.GormEnhancer
+import org.grails.datastore.gorm.GormRegistry
import org.grails.datastore.gorm.GormStaticApi
-import org.grails.datastore.mapping.core.connections.ConnectionSource
import org.grails.datastore.mapping.model.PersistentEntity
import org.grails.gorm.graphql.binding.GraphQLDataBinder
import org.grails.gorm.graphql.fetcher.BindingGormDataFetcher
@@ -157,7 +156,7 @@ class GraphQLDataFetcherManagerSpec extends Specification {
void "test registering a binding fetcher"() {
given:
- GormEnhancer.STATIC_APIS.put(ConnectionSource.DEFAULT, ['java.lang.String': Mock(GormStaticApi)])
+ GormRegistry.instance.staticApiRegistry.register('java.lang.String', Mock(GormStaticApi))
when:
manager.registerBindingDataFetcher(String, mockBindingFetcher)
diff --git a/grails-data-hibernate5/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormApiFactory.groovy b/grails-data-hibernate5/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormApiFactory.groovy
new file mode 100644
index 0000000000..9a89310cec
--- /dev/null
+++ b/grails-data-hibernate5/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormApiFactory.groovy
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.grails.orm.hibernate
+
+import groovy.transform.CompileStatic
+
+import org.grails.datastore.gorm.DatastoreResolver
+import org.grails.datastore.gorm.DefaultGormApiFactory
+import org.grails.datastore.gorm.GormApiFactory
+import org.grails.datastore.gorm.GormInstanceApi
+import org.grails.datastore.gorm.GormRegistry
+import org.grails.datastore.gorm.GormStaticApi
+import org.grails.datastore.gorm.GormValidationApi
+import org.grails.datastore.gorm.finders.FinderMethod
+import org.grails.datastore.mapping.model.MappingContext
+
+/**
+ * {@link GormApiFactory} that produces Hibernate 5-specific API instances, ensuring that
+ * {@code withNewSession} and related lifecycle methods use the Hibernate {@code SessionFactory}
+ * binding rather than the generic GORM {@code DatastoreUtils} path.
+ */
+@CompileStatic
+class HibernateGormApiFactory implements GormApiFactory {
+
+ private final ClassLoader classLoader
+
+ HibernateGormApiFactory(ClassLoader classLoader) {
+ this.classLoader = classLoader
+ }
+
+ @Override
+ <D> GormStaticApi<D> createStaticApi(Class<D> persistentClass, MappingContext mappingContext, DatastoreResolver resolver, String qualifier, GormRegistry registry) {
+ HibernateDatastore hds = (HibernateDatastore) resolver.resolve()
+ List<FinderMethod> finders = new DefaultGormApiFactory().createDynamicFinders(resolver, mappingContext)
+ return new HibernateGormStaticApi<D>(persistentClass, hds, finders, classLoader, hds.getTransactionManager())
+ }
+
+ @Override
+ <D> GormInstanceApi<D> createInstanceApi(Class<D> persistentClass, MappingContext mappingContext, DatastoreResolver resolver, GormRegistry registry, boolean failOnError, boolean markDirty) {
+ HibernateDatastore hds = (HibernateDatastore) resolver.resolve()
+ GormInstanceApi<D> instanceApi = new HibernateGormInstanceApi<D>(persistentClass, hds, classLoader)
+ instanceApi.failOnError = failOnError
+ instanceApi.markDirty = markDirty
+ return instanceApi
+ }
+
+ @Override
+ <D> GormValidationApi<D> createValidationApi(Class<D> persistentClass, MappingContext mappingContext, DatastoreResolver resolver, GormRegistry registry) {
+ HibernateDatastore hds = (HibernateDatastore) resolver.resolve()
+ return new HibernateGormValidationApi<D>(persistentClass, hds, classLoader)
+ }
+
+ @Override
+ List<FinderMethod> createDynamicFinders(DatastoreResolver datastoreResolver, MappingContext mappingContext) {
+ new DefaultGormApiFactory().createDynamicFinders(datastoreResolver, mappingContext)
+ }
+}
diff --git a/grails-data-hibernate5/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormEnhancer.groovy b/grails-data-hibernate5/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormEnhancer.groovy
index 9a47fb8c41..7b2f8f83b1 100644
--- a/grails-data-hibernate5/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormEnhancer.groovy
+++ b/grails-data-hibernate5/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormEnhancer.groovy
@@ -24,9 +24,11 @@ import org.springframework.transaction.PlatformTransactionManager
import org.grails.datastore.gorm.GormEnhancer
import org.grails.datastore.gorm.GormInstanceApi
+import org.grails.datastore.gorm.GormRegistry
import org.grails.datastore.gorm.GormStaticApi
import org.grails.datastore.gorm.GormValidationApi
import org.grails.datastore.mapping.core.Datastore
+import org.grails.datastore.mapping.core.connections.ConnectionSource
import org.grails.datastore.mapping.core.connections.ConnectionSourceSettings
/**
@@ -48,6 +50,7 @@ class HibernateGormEnhancer extends GormEnhancer {
super(datastore, transactionManager, settings)
}
+
@Override
protected <D> GormStaticApi<D> getStaticApi(Class<D> cls, String qualifier) {
HibernateDatastore hibernateDatastore = (HibernateDatastore) datastore
@@ -75,6 +78,6 @@ class HibernateGormEnhancer extends GormEnhancer {
@Override
protected void registerConstraints(Datastore datastore) {
- // no-op
+ GormRegistry.instance.registerApiFactory(HibernateDatastore, new HibernateGormApiFactory(Thread.currentThread().contextClassLoader))
}
}
diff --git a/grails-data-hibernate5/core/src/test/groovy/org/apache/grails/data/hibernate5/core/GrailsDataHibernate5TckManager.groovy b/grails-data-hibernate5/core/src/test/groovy/org/apache/grails/data/hibernate5/core/GrailsDataHibernate5TckManager.groovy
index b6a730ae32..74c435eba9 100644
--- a/grails-data-hibernate5/core/src/test/groovy/org/apache/grails/data/hibernate5/core/GrailsDataHibernate5TckManager.groovy
+++ b/grails-data-hibernate5/core/src/test/groovy/org/apache/grails/data/hibernate5/core/GrailsDataHibernate5TckManager.groovy
@@ -53,7 +53,8 @@ class GrailsDataHibernate5TckManager extends GrailsDataTckManager {
ApplicationContext applicationContext
HibernateDatastore multiDataSourceDatastore
HibernateDatastore multiTenantMultiDataSourceDatastore
- Map grailsConfig
+ ConfigObject grailsConfig = new ConfigObject()
+ boolean isTransactional = true
@Override
void setup(Class<? extends Specification> spec) {
@@ -63,20 +64,14 @@ class GrailsDataHibernate5TckManager extends GrailsDataTckManager {
@Override
Session createSession() {
- ConfigObject config = new ConfigObject()
+ System.setProperty('hibernate5.gorm.suite', "true")
+ grailsConfig.dataSource.dbCreate = grailsConfig.dataSource.dbCreate ?: "create-drop"
+ grailsApplication = new DefaultGrailsApplication(domainClasses as Class[], new GroovyClassLoader(GrailsDataHibernate5TckManager.getClassLoader()))
if (grailsConfig) {
- config.putAll(grailsConfig)
- }
- if (!config.containsKey('dataSource.dbCreate') && !config.dataSource.containsKey('dbCreate')) {
- config.dataSource.dbCreate = "create-drop"
+ grailsApplication.config.putAll(grailsConfig)
}
- boolean isTransactional = true
-
- System.setProperty('hibernate5.gorm.suite', "true")
- grailsApplication = new DefaultGrailsApplication(domainClasses, new GroovyClassLoader(GrailsDataHibernate5TckManager.getClassLoader()))
- grailsApplication.config.putAll(config)
- hibernateDatastore = new HibernateDatastore(DatastoreUtils.createPropertyResolver(config), domainClasses)
+ hibernateDatastore = new HibernateDatastore(DatastoreUtils.createPropertyResolver(grailsConfig), domainClasses as Class[])
transactionManager = hibernateDatastore.getTransactionManager()
sessionFactory = hibernateDatastore.sessionFactory
if (transactionStatus == null && isTransactional) {
diff --git a/grails-data-hibernate5/core/src/test/groovy/org/grails/datastore/gorm/GormEnhancerCleanupSpec.groovy b/grails-data-hibernate5/core/src/test/groovy/org/grails/datastore/gorm/GormEnhancerCleanupSpec.groovy
index 9686265a1c..aa382c9697 100644
--- a/grails-data-hibernate5/core/src/test/groovy/org/grails/datastore/gorm/GormEnhancerCleanupSpec.groovy
+++ b/grails-data-hibernate5/core/src/test/groovy/org/grails/datastore/gorm/GormEnhancerCleanupSpec.groovy
@@ -20,7 +20,7 @@ package org.grails.datastore.gorm
import grails.gorm.annotation.Entity
import grails.gorm.tests.HibernateGormDatastoreSpec
-import org.grails.datastore.mapping.core.Datastore
+import org.grails.datastore.mapping.core.connections.ConnectionSource
class GormEnhancerCleanupSpec extends HibernateGormDatastoreSpec {
@@ -28,56 +28,33 @@ class GormEnhancerCleanupSpec extends HibernateGormDatastoreSpec {
manager.registerDomainClasses(CleanupEntity)
}
- void "Test that GormEnhancer.close() removes datastore from DATASTORES registry"() {
+ void "GormRegistry tracks entity-to-datastore mapping for registered entities"() {
given:
- def enhancerClass = GormEnhancer.class
- def datastoresField = enhancerClass.getDeclaredField("DATASTORES")
- datastoresField.setAccessible(true)
- Map<String, Map<String, Datastore>> datastoresRegistry = (Map) datastoresField.get(null)
+ def registry = GormRegistry.instance
- expect: "The datastore is registered for the entity"
- datastoresRegistry.get("default")?.get(CleanupEntity.name) == datastore
+ expect: "CleanupEntity maps to the active datastore"
+ registry.getDatastore(CleanupEntity, ConnectionSource.DEFAULT) == datastore
- when: "The datastore is closed"
- datastore.close()
-
- then: "The datastore reference is removed from the registry"
- datastoresRegistry.get("default")?.get(CleanupEntity.name) == null
+ and: "A static API is registered for CleanupEntity"
+ registry.getStaticApi(CleanupEntity) != null
}
- void "Test that GormEnhancer.close() does not mutate maps via withDefault"() {
+ void "GormRegistry.removeDatastore clears entity and static API entries"() {
given:
- def enhancerClass = GormEnhancer.class
- def staticApisField = enhancerClass.getDeclaredField("STATIC_APIS")
- staticApisField.setAccessible(true)
- Map staticApisRegistry = (Map) staticApisField.get(null)
+ def registry = GormRegistry.instance
+
+ expect: "entries are present before removal"
+ registry.getDatastore(CleanupEntity, ConnectionSource.DEFAULT) == datastore
+ registry.getStaticApi(CleanupEntity) != null
- String unknownQualifier = "unknown_tenant_" + System.currentTimeMillis()
-
- expect: "The unknown qualifier is not in the map"
- !staticApisRegistry.containsKey(unknownQualifier)
+ when: "the datastore is removed from the registry"
+ registry.removeDatastore(datastore)
- when: "Closing a datastore with an unknown qualifier (simulated)"
- // This is tricky because we need a datastore that 'claims' to have this qualifier
- // We'll just manually call close() with a mock/stub if possible,
- // but GormEnhancer uses 'this.datastore' internally.
-
- // Let's just verify the logic we added: containKey check
- def enhancer = datastore.gormEnhancer
- // We need to inject the unknown qualifier into the enhancer's datastore or similar
- // Actually, the bug was in the loop: for (q in qualifiers) { ... STATIC_APIS.get(q) ... }
- // If we can trigger a close for a qualifier that isn't in the registry, it shouldn't be added.
-
- // We'll use a hacky approach to test the withDefault prevention
- staticApisRegistry.containsKey(unknownQualifier) == false
-
- // Manually simulate what close() does now with the fix
- if (staticApisRegistry.containsKey(unknownQualifier)) {
- staticApisRegistry.get(unknownQualifier).remove("SomeClass")
- }
+ then: "entity-to-datastore mapping is cleared"
+ registry.getDatastore(CleanupEntity, ConnectionSource.DEFAULT) == null
- then: "The qualifier was NOT added to the map"
- !staticApisRegistry.containsKey(unknownQualifier)
+ and: "static API is also cleared"
+ registry.getStaticApi(CleanupEntity) == null
}
}
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormApiFactory.groovy b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormApiFactory.groovy
new file mode 100644
index 0000000000..03bc49d139
--- /dev/null
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormApiFactory.groovy
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.grails.orm.hibernate
+
+import groovy.transform.CompileStatic
+
+import org.grails.datastore.gorm.DatastoreResolver
+import org.grails.datastore.gorm.DefaultGormApiFactory
+import org.grails.datastore.gorm.GormApiFactory
+import org.grails.datastore.gorm.GormInstanceApi
+import org.grails.datastore.gorm.GormRegistry
+import org.grails.datastore.gorm.GormStaticApi
+import org.grails.datastore.gorm.GormValidationApi
+import org.grails.datastore.gorm.finders.FinderMethod
+import org.grails.datastore.mapping.model.MappingContext
+
+/**
+ * {@link GormApiFactory} that produces Hibernate 7-specific API instances, ensuring that
+ * {@code withNewSession} and related lifecycle methods use the Hibernate {@code SessionFactory}
+ * binding rather than the generic GORM {@code DatastoreUtils} path.
+ */
+@CompileStatic
+class HibernateGormApiFactory implements GormApiFactory {
+
+ private final ClassLoader classLoader
+
+ HibernateGormApiFactory(ClassLoader classLoader) {
+ this.classLoader = classLoader
+ }
+
+ @Override
+ <D> GormStaticApi<D> createStaticApi(Class<D> persistentClass, MappingContext mappingContext, DatastoreResolver resolver, String qualifier, GormRegistry registry) {
+ HibernateDatastore hds = (HibernateDatastore) resolver.resolve()
+ List<FinderMethod> finders = new DefaultGormApiFactory().createDynamicFinders(resolver, mappingContext)
+ return new HibernateGormStaticApi<D>(persistentClass, hds, finders, classLoader, hds.getTransactionManager(), qualifier)
+ }
+
+ @Override
+ <D> GormInstanceApi<D> createInstanceApi(Class<D> persistentClass, MappingContext mappingContext, DatastoreResolver resolver, GormRegistry registry, boolean failOnError, boolean markDirty) {
+ HibernateDatastore hds = (HibernateDatastore) resolver.resolve()
+ GormInstanceApi<D> instanceApi = new HibernateGormInstanceApi<D>(persistentClass, hds, classLoader)
+ instanceApi.failOnError = failOnError
+ instanceApi.markDirty = markDirty
+ return instanceApi
+ }
+
+ @Override
+ <D> GormValidationApi<D> createValidationApi(Class<D> persistentClass, MappingContext mappingContext, DatastoreResolver resolver, GormRegistry registry) {
+ HibernateDatastore hds = (HibernateDatastore) resolver.resolve()
+ return new HibernateGormValidationApi<D>(persistentClass, hds, classLoader)
+ }
+
+ @Override
+ List<FinderMethod> createDynamicFinders(DatastoreResolver datastoreResolver, MappingContext mappingContext) {
+ new DefaultGormApiFactory().createDynamicFinders(datastoreResolver, mappingContext)
+ }
+}
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormEnhancer.groovy b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormEnhancer.groovy
index 1349ae24f6..29e4e5b256 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormEnhancer.groovy
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormEnhancer.groovy
@@ -38,9 +38,11 @@ import org.springframework.transaction.PlatformTransactionManager
import org.grails.datastore.gorm.GormEnhancer
import org.grails.datastore.gorm.GormInstanceApi
+import org.grails.datastore.gorm.GormRegistry
import org.grails.datastore.gorm.GormStaticApi
import org.grails.datastore.gorm.GormValidationApi
import org.grails.datastore.mapping.core.Datastore
+import org.grails.datastore.mapping.core.connections.ConnectionSource
import org.grails.datastore.mapping.core.connections.ConnectionSourceSettings
/**
@@ -90,7 +92,7 @@ class HibernateGormEnhancer extends GormEnhancer {
@Override
protected void registerConstraints(Datastore datastore) {
- // no-op
+ GormRegistry.instance.registerApiFactory(HibernateDatastore, new HibernateGormApiFactory(Thread.currentThread().contextClassLoader))
}
public static <D> GormStaticApi<D> findStaticApi(Class<D> cls, String qualifier) {
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/datastore/gorm/GormEnhancerCleanupSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/datastore/gorm/GormEnhancerCleanupSpec.groovy
index 6874a037e6..fffe874656 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/datastore/gorm/GormEnhancerCleanupSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/datastore/gorm/GormEnhancerCleanupSpec.groovy
@@ -16,9 +16,7 @@ package org.grails.datastore.gorm
import grails.gorm.annotation.Entity
import grails.gorm.tests.HibernateGormDatastoreSpec
-import org.grails.datastore.mapping.core.Datastore
-import spock.lang.Specification
-import java.util.concurrent.ConcurrentHashMap
+import org.grails.datastore.mapping.core.connections.ConnectionSource
class GormEnhancerCleanupSpec extends HibernateGormDatastoreSpec {
@@ -26,56 +24,33 @@ class GormEnhancerCleanupSpec extends HibernateGormDatastoreSpec {
manager.registerDomainClasses(CleanupEntity)
}
- void "Test that GormEnhancer.close() removes datastore from DATASTORES registry"() {
+ void "GormRegistry tracks entity-to-datastore mapping for registered entities"() {
given:
- def enhancerClass = GormEnhancer.class
- def datastoresField = enhancerClass.getDeclaredField("DATASTORES")
- datastoresField.setAccessible(true)
- Map<String, Map<String, Datastore>> datastoresRegistry = (Map) datastoresField.get(null)
+ def registry = GormRegistry.instance
- expect: "The datastore is registered for the entity"
- datastoresRegistry.get("default")?.get(CleanupEntity.name) == datastore
+ expect: "CleanupEntity maps to the active datastore"
+ registry.getDatastore(CleanupEntity, ConnectionSource.DEFAULT) == datastore
- when: "The datastore is closed"
- datastore.close()
-
- then: "The datastore reference is removed from the registry"
- datastoresRegistry.get("default")?.get(CleanupEntity.name) == null
+ and: "A static API is registered for CleanupEntity"
+ registry.getStaticApi(CleanupEntity) != null
}
- void "Test that GormEnhancer.close() does not mutate maps via withDefault"() {
+ void "GormRegistry.removeDatastore clears entity and static API entries"() {
given:
- def enhancerClass = GormEnhancer.class
- def staticApisField = enhancerClass.getDeclaredField("STATIC_APIS")
- staticApisField.setAccessible(true)
- Map staticApisRegistry = (Map) staticApisField.get(null)
+ def registry = GormRegistry.instance
+
+ expect: "entries are present before removal"
+ registry.getDatastore(CleanupEntity, ConnectionSource.DEFAULT) == datastore
+ registry.getStaticApi(CleanupEntity) != null
- String unknownQualifier = "unknown_tenant_" + System.currentTimeMillis()
-
- expect: "The unknown qualifier is not in the map"
- !staticApisRegistry.containsKey(unknownQualifier)
+ when: "the datastore is removed from the registry"
+ registry.removeDatastore(datastore)
- when: "Closing a datastore with an unknown qualifier (simulated)"
- // This is tricky because we need a datastore that 'claims' to have this qualifier
- // We'll just manually call close() with a mock/stub if possible,
- // but GormEnhancer uses 'this.datastore' internally.
-
- // Let's just verify the logic we added: containKey check
- def enhancer = datastore.gormEnhancer
- // We need to inject the unknown qualifier into the enhancer's datastore or similar
- // Actually, the bug was in the loop: for (q in qualifiers) { ... STATIC_APIS.get(q) ... }
- // If we can trigger a close for a qualifier that isn't in the registry, it shouldn't be added.
-
- // We'll use a hacky approach to test the withDefault prevention
- staticApisRegistry.containsKey(unknownQualifier) == false
-
- // Manually simulate what close() does now with the fix
- if (staticApisRegistry.containsKey(unknownQualifier)) {
- staticApisRegistry.get(unknownQualifier).remove("SomeClass")
- }
+ then: "entity-to-datastore mapping is cleared"
+ registry.getDatastore(CleanupEntity, ConnectionSource.DEFAULT) == null
- then: "The qualifier was NOT added to the map"
- !staticApisRegistry.containsKey(unknownQualifier)
+ and: "static API is also cleared"
+ registry.getStaticApi(CleanupEntity) == null
}
}
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormInstanceApiSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormInstanceApiSpec.groovy
index c1e3fd24fb..afad06923e 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormInstanceApiSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormInstanceApiSpec.groovy
@@ -22,6 +22,8 @@ import grails.gorm.tests.HibernateGormDatastoreSpec
import grails.gorm.annotation.Entity
import grails.gorm.hibernate.HibernateEntity
import grails.gorm.transactions.Rollback
+import org.grails.datastore.gorm.GormRegistry
+import org.grails.datastore.mapping.core.connections.ConnectionSource
import org.hibernate.FlushMode
import org.grails.orm.hibernate.query.SelectHqlQuery
@@ -34,19 +36,19 @@ class HibernateGormInstanceApiSpec extends HibernateGormDatastoreSpec {
void "Test that HibernateGormInstanceApi uses the shared template from the datastore"() {
given:
- def enhancer = manager.hibernateDatastore.gormEnhancer
- def api = enhancer.getInstanceApi(PersonInstanceApi)
+ def api = (HibernateGormInstanceApi) GormRegistry.instance.getInstanceApi(PersonInstanceApi.name)
expect:
+ api instanceof HibernateGormInstanceApi
api.hibernateTemplate.is(manager.hibernateDatastore.getHibernateTemplate())
}
void "Test that HibernateGormInstanceApi uses the shared InstanceApiHelper from the datastore"() {
given:
- def enhancer = manager.hibernateDatastore.gormEnhancer
- def api = enhancer.getInstanceApi(PersonInstanceApi)
+ def api = (HibernateGormInstanceApi) GormRegistry.instance.getInstanceApi(PersonInstanceApi.name)
expect:
+ api instanceof HibernateGormInstanceApi
api.instanceApiHelper.is(manager.hibernateDatastore.getInstanceApiHelper())
}
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormStaticApiSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormStaticApiSpec.groovy
index 8b64a33847..13e995c66c 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormStaticApiSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormStaticApiSpec.groovy
@@ -23,6 +23,7 @@ package org.grails.orm.hibernate
import grails.gorm.tests.HibernateGormDatastoreSpec
import grails.gorm.annotation.Entity
import grails.gorm.tests.entities.Club
+import org.grails.datastore.mapping.core.connections.ConnectionSource
import org.hibernate.jpa.AvailableHints
class HibernateGormStaticApiSpec extends HibernateGormDatastoreSpec {
@@ -34,7 +35,7 @@ class HibernateGormStaticApiSpec extends HibernateGormDatastoreSpec {
void "Test that HibernateGormStaticApi uses the shared template from the datastore"() {
given:
def enhancer = manager.hibernateDatastore.gormEnhancer
- def api = enhancer.getStaticApi(HibernateGormStaticApiEntity)
+ def api = enhancer.getStaticApi(HibernateGormStaticApiEntity, ConnectionSource.DEFAULT)
expect:
api.hibernateTemplate.is(manager.hibernateDatastore.getHibernateTemplate())
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormValidationApiSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormValidationApiSpec.groovy
index f1ddff8bc1..8c18ad838a 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormValidationApiSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormValidationApiSpec.groovy
@@ -20,6 +20,7 @@ package org.grails.orm.hibernate
import grails.gorm.annotation.Entity
import grails.gorm.transactions.Rollback
+import org.grails.datastore.gorm.GormRegistry
import org.grails.datastore.mapping.core.DatastoreUtils
import org.grails.orm.hibernate.cfg.Settings
import org.springframework.core.env.PropertyResolver
@@ -39,10 +40,10 @@ class HibernateGormValidationApiSpec extends Specification {
void "Test that HibernateGormValidationApi uses the shared template from the datastore"() {
given:
- def enhancer = hibernateDatastore.gormEnhancer
- def api = enhancer.getValidationApi(ValidatedBook)
+ def api = (HibernateGormValidationApi) GormRegistry.instance.getValidationApi(ValidatedBook.name)
expect:
+ api instanceof HibernateGormValidationApi
api.hibernateTemplate.is(hibernateDatastore.getHibernateTemplate())
}
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/SchemaTenantGormEnhancerSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/SchemaTenantGormEnhancerSpec.groovy
index 4ac136e57f..4e52d357fe 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/SchemaTenantGormEnhancerSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/SchemaTenantGormEnhancerSpec.groovy
@@ -22,7 +22,6 @@ import java.lang.reflect.Modifier
import grails.gorm.MultiTenant
import grails.gorm.annotation.Entity
-import grails.gorm.multitenancy.CurrentTenant
import org.grails.datastore.gorm.GormEntity
import org.grails.datastore.mapping.core.DatastoreUtils
import org.grails.datastore.mapping.multitenancy.AllTenantsResolver
@@ -162,7 +161,6 @@ class SchemaTenantGormEnhancerSpec extends Specification {
}
@Entity
-@CurrentTenant
class SchemaTenantBook implements GormEntity<SchemaTenantBook>, MultiTenant<SchemaTenantBook> {
String title
static constraints = { title blank: false }
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsIdentityGeneratorSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsIdentityGeneratorSpec.groovy
index bc051b5d56..12325130e2 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsIdentityGeneratorSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsIdentityGeneratorSpec.groovy
@@ -33,6 +33,11 @@ import org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIdentityGenera
class GrailsIdentityGeneratorSpec extends HibernateGormDatastoreSpec {
+ @Override
+ void setupSpec() {
+ manager.registerDomainClasses(TestEntity, ChildEntity)
+ }
+
def "should configure identity generator and set column as identity"() {
given:
def context = Mock(GeneratorCreationContext)
diff --git a/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/base/GrailsDataTckManager.groovy b/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/base/GrailsDataTckManager.groovy
index 4ba4d8f439..ade0126263 100644
--- a/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/base/GrailsDataTckManager.groovy
+++ b/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/base/GrailsDataTckManager.groovy
@@ -31,8 +31,7 @@ abstract class GrailsDataTckManager {
abstract Session createSession()
- private Set<Class> domainClasses = [
- ]
+ private Set<Class> domainClasses = []
/**
* Returns a defensive copy of the registered domain classes.
@@ -42,9 +41,16 @@ abstract class GrailsDataTckManager {
domainClasses as Class[]
}
+ @Deprecated
+ void addAllDomainClasses(Collection<Class> classes) {
+ if (classes) {
+ registerDomainClasses(classes as Class[])
+ }
+ }
+
/**
- * Registers the domain classes that will be available when testing.
- * @param classes The classes to register
+ * Adds all the specified classes to the domain classes list.
+ * @param classes The classes to add
*/
void registerDomainClasses(Class... classes) {
if (classes) {