This is an automated email from the ASF dual-hosted git repository. borinquenkid pushed a commit to branch 8.0.x-hibernate7.gorm-scaling-clean in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 1658d7aae7e332abc7251261e6cdcab36f4138f8 Author: Walter Duque de Estrada <[email protected]> AuthorDate: Fri Jun 26 12:43:05 2026 -0500 Fix CI compilation failures: static type errors, duplicate import, and debug spec cleanup - HibernateGormStaticApi: replace bare `persistentEntity` references (from the now-removed AbstractGormApi field) with `gormPersistentEntity` property calls in buildWhereHql, validateWherePropertyName, getAllInternal, prepareHqlQuery, firePostQueryEvent, and firePreQueryEvent; fixes 17 @CompileStatic errors that appeared after the GormRegistry migration removed the field - HibernateGormStaticApi: remove duplicate `import...Query` (was shadowing the aliased `import...Query as GormQuery`); update two bare Query usages to GormQuery - HibernateEntity: replace removed GormEnhancer.findStaticApi() call with GormRegistry.findStaticApi() so currentHibernateStaticApi() compiles under @CompileStatic - grails-data-mongodb: remove 7 debug/duplicate geo test files (DebugGeoJSONSpec, DebugGeoJSONDecodeSpec, DebugGeoJSONQuerySpec, DebugGetSpec, GeoPlaceTest, GeoRetrieveTest, SimplePlaceTest) that imported a non-existent MongoDatastoreSpec and whose coverage is fully provided by GeoJSONTypePersistenceSpec - grails-datamapping-tck: add Javadoc to four replacement specs explaining why CrossLayerMultiDataSourceSpec and CrossLayerMultiTenantMultiDataSourceSpec were removed and where their coverage now lives Co-Authored-By: Claude Sonnet 4.6 <[email protected]> --- .../grails/gorm/hibernate/HibernateEntity.groovy | 4 +- .../orm/hibernate/HibernateGormStaticApi.groovy | 19 ++--- .../gorm/mongo/DebugGeoJSONDecodeSpec.groovy | 82 ---------------------- .../gorm/mongo/DebugGeoJSONQuerySpec.groovy | 66 ----------------- .../datastore/gorm/mongo/DebugGeoJSONSpec.groovy | 73 ------------------- .../datastore/gorm/mongo/DebugGetSpec.groovy | 54 -------------- .../datastore/gorm/mongo/GeoPlaceTest.groovy | 66 ----------------- .../datastore/gorm/mongo/GeoRetrieveTest.groovy | 64 ----------------- .../datastore/gorm/mongo/SimplePlaceTest.groovy | 52 -------------- .../tests/DataServiceConnectionRoutingSpec.groovy | 12 ++++ ...aServiceMultiTenantConnectionRoutingSpec.groovy | 11 +++ .../tck/tests/DomainMultiDataSourceSpec.groovy | 12 ++++ .../DomainMultiTenantMultiDataSourceSpec.groovy | 11 +++ 13 files changed, 59 insertions(+), 467 deletions(-) diff --git a/grails-data-hibernate7/core/src/main/groovy/grails/gorm/hibernate/HibernateEntity.groovy b/grails-data-hibernate7/core/src/main/groovy/grails/gorm/hibernate/HibernateEntity.groovy index 23677dd143..c85676f784 100644 --- a/grails-data-hibernate7/core/src/main/groovy/grails/gorm/hibernate/HibernateEntity.groovy +++ b/grails-data-hibernate7/core/src/main/groovy/grails/gorm/hibernate/HibernateEntity.groovy @@ -23,7 +23,7 @@ import groovy.transform.Generated import org.codehaus.groovy.runtime.InvokerHelper import org.grails.datastore.gorm.GormEntity -import org.grails.datastore.gorm.GormEnhancer +import org.grails.datastore.gorm.GormRegistry import org.grails.datastore.mapping.model.PersistentEntity import org.grails.datastore.mapping.model.types.Association import org.grails.datastore.mapping.model.types.ToOne @@ -141,7 +141,7 @@ trait HibernateEntity<D> extends GormEntity<D> { @Generated private static HibernateGormStaticApi currentHibernateStaticApi() { - (HibernateGormStaticApi) GormEnhancer.findStaticApi(this) + (HibernateGormStaticApi) GormRegistry.findStaticApi(this) } /** diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy index c904016a90..06a1e153c3 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy @@ -44,7 +44,6 @@ import org.grails.datastore.mapping.model.PersistentProperty import org.grails.datastore.mapping.model.config.GormProperties import org.grails.datastore.mapping.model.types.Basic import org.grails.datastore.mapping.model.types.Simple -import org.grails.datastore.mapping.query.Query import org.grails.datastore.mapping.query.Restrictions import org.grails.datastore.mapping.query.api.BuildableCriteria import org.grails.datastore.mapping.query.event.PostQueryEvent @@ -214,7 +213,7 @@ class HibernateGormStaticApi<D> extends GormStaticApi<D> { List<D> list(Map params) { PersistentEntity entity = getGormPersistentEntity() HqlQueryContext ctx = HqlQueryContext.prepare(entity, null, null, null, params, new HashMap<>(), false, false) - Query q = HibernateHqlQueryCreator.createHqlQuery(getHibernateDatastore(), getHibernateDatastore().getSessionFactory(), entity, ctx) + GormQuery q = HibernateHqlQueryCreator.createHqlQuery(getHibernateDatastore(), getHibernateDatastore().getSessionFactory(), entity, ctx) if (HqlListQueryBuilder.isPaged(params)) { return (List<D>) new PagedResultList(q) } @@ -439,17 +438,19 @@ class HibernateGormStaticApi<D> extends GormStaticApi<D> { } private String buildWhereHql(Map<String, Object> queryMap) { + PersistentEntity pe = gormPersistentEntity String whereClause = queryMap.collect { String key, Object value -> String propertyName = validateWherePropertyName(key) value == null ? "$propertyName is null" : "$propertyName = :$propertyName" }.join(' and ') - return "from ${persistentEntity.name} where $whereClause" + return "from ${pe.name} where $whereClause" } private String validateWherePropertyName(String propertyName) { - PersistentProperty property = persistentEntity.getPropertyByName(propertyName) + PersistentEntity pe = gormPersistentEntity + PersistentProperty property = pe.getPropertyByName(propertyName) if (property == null || property.name != propertyName) { - throw new IllegalArgumentException("Property [$propertyName] is not a valid property of ${persistentEntity.name}") + throw new IllegalArgumentException("Property [$propertyName] is not a valid property of ${pe.name}") } return propertyName } @@ -507,6 +508,7 @@ class HibernateGormStaticApi<D> extends GormStaticApi<D> { private List<D> getAllInternal(List ids) { if (!ids) return [] + PersistentEntity persistentEntity = gormPersistentEntity String idName = persistentEntity.identity.name String entity = persistentEntity.name Class<?> idType = persistentEntity.identity.type @@ -611,7 +613,7 @@ class HibernateGormStaticApi<D> extends GormStaticApi<D> { } as SessionCallback<D>) } - protected void populateQueryByExample(Session session, Query query, D example) { + protected void populateQueryByExample(Session session, GormQuery query, D example) { PersistentEntity pe = getGormPersistentEntity() MappingContext mappingContext = pe.mappingContext def ea = mappingContext.createEntityAccess(pe, example) @@ -711,6 +713,7 @@ class HibernateGormStaticApi<D> extends GormStaticApi<D> { Map namedParams, Collection positionalParams, Map args) { + PersistentEntity persistentEntity = gormPersistentEntity Map<String, Object> coercedParams = namedParams?.collectEntries { k, v -> [k.toString(), v] } ?: [:] Map<String, Object> coercedArgs = args?.collectEntries { k, v -> [k.toString(), v] } ?: [:] def ctx = HqlQueryContext.prepare(persistentEntity, hql, coercedParams, positionalParams, coercedArgs, new HashMap<>(), isNative, isUpdate) @@ -724,14 +727,14 @@ class HibernateGormStaticApi<D> extends GormStaticApi<D> { protected void firePostQueryEvent(Object result) { def hibernateSession = new HibernateSession(getHibernateDatastore(), getHibernateDatastore().getSessionFactory()) - def hibernateQuery = new HibernateQuery(hibernateSession, (GrailsHibernatePersistentEntity) persistentEntity) + def hibernateQuery = new HibernateQuery(hibernateSession, (GrailsHibernatePersistentEntity) gormPersistentEntity) def list = result instanceof List ? (List) result : Collections.singletonList(result) getHibernateDatastore().applicationEventPublisher.publishEvent(new PostQueryEvent(getHibernateDatastore(), hibernateQuery, list)) } protected void firePreQueryEvent() { def hibernateSession = new HibernateSession(getHibernateDatastore(), getHibernateDatastore().getSessionFactory()) - def hibernateQuery = new HibernateQuery(hibernateSession, (GrailsHibernatePersistentEntity) persistentEntity) + def hibernateQuery = new HibernateQuery(hibernateSession, (GrailsHibernatePersistentEntity) gormPersistentEntity) getHibernateDatastore().applicationEventPublisher.publishEvent(new PreQueryEvent(getHibernateDatastore(), hibernateQuery)) } diff --git a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DebugGeoJSONDecodeSpec.groovy b/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DebugGeoJSONDecodeSpec.groovy deleted file mode 100644 index 6dbdd4d719..0000000000 --- a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DebugGeoJSONDecodeSpec.groovy +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2026 the original author or authors. - * - * Licensed 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.datastore.gorm.mongo - -import org.apache.grails.data.mongo.core.MongoDatastoreSpec -import grails.mongodb.geo.GeometryCollection -import grails.mongodb.geo.Point -import grails.persistence.Entity - -class DebugGeoJSONDecodeSpec extends MongoDatastoreSpec { - - void setupSpec() { - manager.addAllDomainClasses([PlaceWithGeoJSON]) - } - - void "test simple GeoJSON field"() { - when: "A Place with a single GeoJSON field is saved" - def p = new PlaceWithGeoJSON(point: Point.valueOf(5, 10)) - p.save(flush: true, validate: false) - def savedId = p.id - println "Saved Place with id: ${savedId}, point: ${p.point}" - - and: "The session is cleared" - manager.session.clear() - - and: "Place.get() is called" - println "Calling PlaceWithGeoJSON.get(${savedId})..." - def retrieved = PlaceWithGeoJSON.get(savedId) - println "Retrieved: ${retrieved}" - - then: "The Place should be retrieved" - retrieved != null - retrieved.id == savedId - retrieved.point == Point.valueOf(5, 10) - } - - void "test GeoJSON collection field"() { - when: "A Place with a GeometryCollection is saved" - def col = new GeometryCollection() - col << Point.valueOf(5, 10) - println "Created GeometryCollection: ${col}" - - def p = new PlaceWithGeoJSON(geometryCollection: col) - p.save(flush: true, validate: false) - def savedId = p.id - println "Saved Place with id: ${savedId}, geomCollection: ${p.geometryCollection}" - - and: "The session is cleared" - manager.session.clear() - - and: "Place.get() is called" - println "Calling PlaceWithGeoJSON.get(${savedId})..." - def retrieved = PlaceWithGeoJSON.get(savedId) - println "Retrieved: ${retrieved}" - - then: "The Place should be retrieved" - retrieved != null - retrieved.id == savedId - retrieved.geometryCollection == col - } -} - -@Entity -class PlaceWithGeoJSON { - Long id - Point point - GeometryCollection geometryCollection -} diff --git a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DebugGeoJSONQuerySpec.groovy b/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DebugGeoJSONQuerySpec.groovy deleted file mode 100644 index 4da4ac471c..0000000000 --- a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DebugGeoJSONQuerySpec.groovy +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2026 the original author or authors. - * - * Licensed 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.datastore.gorm.mongo - -import org.apache.grails.data.mongo.core.MongoDatastoreSpec -import grails.mongodb.geo.GeometryCollection -import grails.mongodb.geo.Point -import grails.persistence.Entity -import com.mongodb.client.MongoCollection -import org.bson.Document - -class DebugGeoJSONQuerySpec extends MongoDatastoreSpec { - - void setupSpec() { - manager.addAllDomainClasses([PlaceWithGeoJSONQuery]) - } - - void "test raw query for GeoJSON collection field"() { - when: "A Place with a GeometryCollection is saved" - def col = new GeometryCollection() - col << Point.valueOf(5, 10) - - def p = new PlaceWithGeoJSONQuery(geometryCollection: col) - p.save(flush: true, validate: false) - def savedId = p.id - println "Saved Place with id: ${savedId}" - - and: "The session is cleared" - manager.session.clear() - - and: "We do a raw query for the document" - def entity = manager.mongoDatastore.mappingContext.getPersistentEntity(PlaceWithGeoJSONQuery.name) - def collection = manager.session.getCollection(entity) - println "Collection: ${collection}" - - def query = new Document('_id', savedId) - println "Query: ${query}" - - def doc = collection.find(query).first() - println "Raw document found: ${doc}" - - then: "The document should exist" - doc != null - } -} - -@Entity -class PlaceWithGeoJSONQuery { - Long id - Point point - GeometryCollection geometryCollection -} diff --git a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DebugGeoJSONSpec.groovy b/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DebugGeoJSONSpec.groovy deleted file mode 100644 index 749e14cfeb..0000000000 --- a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DebugGeoJSONSpec.groovy +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2026 the original author or authors. - * - * Licensed 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.datastore.gorm.mongo - -import org.apache.grails.data.mongo.core.MongoDatastoreSpec -import grails.mongodb.geo.Point -import grails.persistence.Entity -import com.mongodb.client.MongoCollection -import org.bson.Document - -@Entity -class DebugPlace { - Long id - String name - Point point - - static mapping = { - point geoIndex: '2dsphere' - } -} - -class DebugGeoJSONSpec extends MongoDatastoreSpec { - - void setupSpec() { - manager.addAllDomainClasses([DebugPlace]) - } - - void "test debug place save and retrieve"() { - when: "save a place with a point" - def point = new Point(5, 10) - def p = new DebugPlace(name: "Test", point: point) - println "Before save: id=${p.id}" - p.save(flush: true, validate: false) - println "After save: id=${p.id}, object=${p}" - - then: "id should be set" - p.id != null - - when: "check mongodb directly" - MongoCollection<Document> col = manager.mongoDatastore.mongoClient - .getDatabase("test") - .getCollection("debugPlace") - def allDocs = col.find().into([]) - println "Documents in MongoDB: ${allDocs.size()}" - allDocs.each { println " $it" } - - then: "document should exist" - allDocs.size() == 1 - - when: "clear session and retrieve" - manager.session.clear() - def retrieved = DebugPlace.get(p.id) - println "Retrieved: ${retrieved}" - - then: "should get the object back" - retrieved != null - retrieved.point == point - } -} diff --git a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DebugGetSpec.groovy b/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DebugGetSpec.groovy deleted file mode 100644 index 0081903edc..0000000000 --- a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DebugGetSpec.groovy +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2026 the original author or authors. - * - * Licensed 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.datastore.gorm.mongo - -import org.apache.grails.data.mongo.core.MongoDatastoreSpec -import grails.persistence.Entity - -class DebugGetSpec extends MongoDatastoreSpec { - - void setupSpec() { - manager.addAllDomainClasses([TestPlace]) - } - - void "test Place.get() returns entity"() { - when: "A simple Place is saved" - def p = new TestPlace(name: "Test") - p.save(flush: true, validate: false) - def savedId = p.id - println "Saved TestPlace with id: ${savedId}" - - and: "The session is cleared" - manager.session.clear() - - and: "TestPlace.get() is called" - println "Calling TestPlace.get(${savedId})..." - def retrieved = TestPlace.get(savedId) - println "Retrieved: ${retrieved}" - - then: "The TestPlace should be retrieved" - retrieved != null - retrieved.id == savedId - retrieved.name == "Test" - } -} - -@Entity -class TestPlace { - Long id - String name -} diff --git a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/GeoPlaceTest.groovy b/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/GeoPlaceTest.groovy deleted file mode 100644 index 1d6fa81777..0000000000 --- a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/GeoPlaceTest.groovy +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.datastore.gorm.mongo - -import org.apache.grails.data.mongo.core.MongoDatastoreSpec -import grails.mongodb.geo.Point -import grails.persistence.Entity -import com.mongodb.client.MongoCollection -import org.bson.Document - -@Entity -class GeoPlace { - Long id - String name - Point point - - static mapping = { - point geoIndex: '2dsphere' - } -} - -class GeoPlaceTest extends MongoDatastoreSpec { - void setupSpec() { - manager.addAllDomainClasses([GeoPlace]) - } - - void "test geo save"() { - when: - def point = new Point(5, 10) - def p = new GeoPlace(name: "Test", point: point) - println "Before save: id=${p.id}" - p.save(flush: true, validate: false) - println "After save: id=${p.id}" - - then: - p.id != null - - when: - // Check MongoDB - MongoCollection<Document> col = manager.mongoDatastore.mongoClient - .getDatabase("test") - .getCollection("geoPlace") - def docs = col.find().into([]) - println "MongoDB has ${docs.size()} docs" - docs.each { println "Doc: $it" } - - then: - docs.size() == 1 - } -} diff --git a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/GeoRetrieveTest.groovy b/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/GeoRetrieveTest.groovy deleted file mode 100644 index 328d8ec80a..0000000000 --- a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/GeoRetrieveTest.groovy +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.datastore.gorm.mongo - -import org.apache.grails.data.mongo.core.MongoDatastoreSpec -import grails.mongodb.geo.Point -import grails.persistence.Entity -import com.mongodb.client.MongoCollection -import org.bson.Document - -@Entity -class GeoPlace2 { - Long id - String name - Point point - - static mapping = { - point geoIndex: '2dsphere' - } -} - -class GeoRetrieveTest extends MongoDatastoreSpec { - void setupSpec() { - manager.addAllDomainClasses([GeoPlace2]) - } - - void "test geo retrieve"() { - when: - def point = new Point(5, 10) - def p = new GeoPlace2(name: "Test", point: point) - p.save(flush: true, validate: false) - def savedId = p.id - println "Saved with id: ${savedId}" - manager.session.clear() - - then: - savedId != null - - when: - def retrieved = GeoPlace2.get(savedId) - println "Retrieved: ${retrieved}" - println "Retrieved.point: ${retrieved?.point}" - - then: - retrieved != null - retrieved.point == point - } -} diff --git a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/SimplePlaceTest.groovy b/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/SimplePlaceTest.groovy deleted file mode 100644 index eb1ab5d81c..0000000000 --- a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/SimplePlaceTest.groovy +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.datastore.gorm.mongo - -import org.apache.grails.data.mongo.core.MongoDatastoreSpec -import grails.mongodb.geo.Point -import grails.persistence.Entity -import com.mongodb.client.MongoCollection -import org.bson.Document - -@Entity -class SimplePlace { - Long id - String name - Point point - - static mapping = { - point geoIndex: '2dsphere' - } -} - -class SimplePlaceTest extends MongoDatastoreSpec { - void setupSpec() { - manager.addAllDomainClasses([SimplePlace]) - } - - void "test simple save"() { - when: - def p = new SimplePlace(name: "Test") - p.save(flush: true, validate: false) - - then: - p.id != null - println "ID after save: ${p.id}" - } -} diff --git a/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DataServiceConnectionRoutingSpec.groovy b/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DataServiceConnectionRoutingSpec.groovy index 3fe965e5cf..efca2d2432 100644 --- a/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DataServiceConnectionRoutingSpec.groovy +++ b/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DataServiceConnectionRoutingSpec.groovy @@ -25,6 +25,18 @@ import org.apache.grails.data.testing.tck.domains.DataServiceRoutingProduct import org.apache.grails.data.testing.tck.domains.DataServiceRoutingProductDataService import org.apache.grails.data.testing.tck.domains.DataServiceRoutingProductService +/** + * Verifies that {@code @Service}-based Data Service operations route to the correct secondary + * datasource via the {@code GormRegistry} selector chain. + * + * <p>Replaces the service-layer portion of the removed {@code CrossLayerMultiDataSourceSpec}. + * That spec obtained a service bean via {@code manager.getServiceForConnection()} — internal + * wiring that changed when {@code GormEnhancer}'s static maps were replaced by a single + * {@code GormRegistry}. Services are now resolved through the registry's connection-routing + * selector ({@code PreferredDatastoreSelector} → {@code QualifiedDatastoreSelector} → + * {@code DefaultDatastoreSelector}). The domain-API routing side is covered by + * {@link DomainMultiDataSourceSpec}.</p> + */ @Requires({ instance.manager?.supportsMultipleDataSources() }) class DataServiceConnectionRoutingSpec extends GrailsDataTckSpec { diff --git a/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DataServiceMultiTenantConnectionRoutingSpec.groovy b/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DataServiceMultiTenantConnectionRoutingSpec.groovy index 9996629baf..b72c03992f 100644 --- a/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DataServiceMultiTenantConnectionRoutingSpec.groovy +++ b/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DataServiceMultiTenantConnectionRoutingSpec.groovy @@ -27,6 +27,17 @@ import org.apache.grails.data.testing.tck.base.GrailsDataTckSpec import org.apache.grails.data.testing.tck.domains.DataServiceRoutingMetric import org.apache.grails.data.testing.tck.domains.DataServiceRoutingMetricService +/** + * Verifies that {@code @Service}-based Data Service operations on a secondary datasource are + * correctly scoped to the active tenant via the {@code GormRegistry} selector chain. + * + * <p>Replaces the service-layer portion of the removed {@code CrossLayerMultiTenantMultiDataSourceSpec}. + * That spec obtained a tenant-scoped service via {@code manager.getServiceForMultiTenantConnection()} + * — internal wiring that no longer exists after the {@code GormEnhancer} static maps were replaced + * by a single {@code GormRegistry}. Services now receive tenant context through the registry's + * selector chain combined with GORM's {@code CurrentTenantHolder}. The domain-API side of this + * contract is covered by {@link DomainMultiTenantMultiDataSourceSpec}.</p> + */ @RestoreSystemProperties @Requires({ instance.manager?.supportsMultiTenantMultiDataSource() }) class DataServiceMultiTenantConnectionRoutingSpec extends GrailsDataTckSpec { diff --git a/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DomainMultiDataSourceSpec.groovy b/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DomainMultiDataSourceSpec.groovy index b7be3ba2e3..c2138763c8 100644 --- a/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DomainMultiDataSourceSpec.groovy +++ b/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DomainMultiDataSourceSpec.groovy @@ -23,6 +23,18 @@ import spock.lang.Requires import org.apache.grails.data.testing.tck.base.GrailsDataTckSpec import org.apache.grails.data.testing.tck.domains.DataServiceRoutingProduct +/** + * Verifies that domain-API CRUD operations route to the correct secondary datasource. + * + * <p>Replaces the domain-layer portion of the removed {@code CrossLayerMultiDataSourceSpec}. + * That spec tested cross-layer visibility (domain save visible via service and vice versa) using + * {@code manager.getServiceForConnection()} — a wiring mechanism that no longer exists after the + * {@code GormRegistry} rewrite. The service-routing side of that contract is now covered by + * {@link DataServiceConnectionRoutingSpec}; data isolation between connections is verified in + * the 'secondary data not visible on default' and 'default data not visible on secondary' features + * below. Cross-layer visibility follows implicitly from both layers routing to the same + * child datastore.</p> + */ @Requires({ instance.manager?.supportsMultipleDataSources() }) class DomainMultiDataSourceSpec extends GrailsDataTckSpec { diff --git a/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DomainMultiTenantMultiDataSourceSpec.groovy b/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DomainMultiTenantMultiDataSourceSpec.groovy index 39efaf8f86..ae9a638195 100644 --- a/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DomainMultiTenantMultiDataSourceSpec.groovy +++ b/grails-datamapping-tck/src/main/groovy/org/apache/grails/data/testing/tck/tests/DomainMultiTenantMultiDataSourceSpec.groovy @@ -26,6 +26,17 @@ import org.grails.datastore.mapping.multitenancy.resolvers.SystemPropertyTenantR import org.apache.grails.data.testing.tck.base.GrailsDataTckSpec import org.apache.grails.data.testing.tck.domains.DataServiceRoutingMetric +/** + * Verifies that domain-API operations on a secondary datasource are correctly scoped to the + * active tenant. + * + * <p>Replaces the domain-layer portion of the removed {@code CrossLayerMultiTenantMultiDataSourceSpec}. + * That spec tested cross-layer visibility under a tenant context (domain save visible via service + * and vice versa) using {@code manager.getServiceForMultiTenantConnection()} — internal wiring + * that changed with the {@code GormRegistry} rewrite. The service-routing side is now covered by + * {@link DataServiceMultiTenantConnectionRoutingSpec}; tenant isolation across connections is + * verified in the 'tenant1 data not visible to tenant2' feature below.</p> + */ @RestoreSystemProperties @Requires({ instance.manager?.supportsMultiTenantMultiDataSource() }) class DomainMultiTenantMultiDataSourceSpec extends GrailsDataTckSpec {
