You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by jd...@apache.org on 2026/09/30 16:41:37 UTC
(grails-core) branch test/document-datamapping-core-finders updated: Drop the distinct() projection from findAllBy and unpend the Mongo OR count spec
This is an automated email from the ASF dual-hosted git repository.
jdaugherty pushed a commit to branch test/document-datamapping-core-finders
in repository https://gitbox.apache.org/repos/asf/grails-core.git
The following commit(s) were added to refs/heads/test/document-datamapping-core-finders by this push:
new 60064c3eff Drop the distinct() projection from findAllBy and unpend the Mongo OR count spec
60064c3eff is described below
commit 60064c3eff18358fac17bb49284abf71fd7f5e08
Author: James Daugherty <jd...@trtn.com>
AuthorDate: Wed Sep 30 12:41:32 2026 -0400
Drop the distinct() projection from findAllBy and unpend the Mongo OR count spec
ListResultFinder applied query.projections().distinct() before list(). The
old FindAllByFinder stopped doing that in 2926a0f644 (#16066), so this was
a regression reintroduced by the refactor rather than a preserved quirk.
GORM for Neo4j only supports count and id projections and threw
UnsupportedOperationException for every findAllBy* call, failing 60 tests
in the Neo4j functional job. Remove the call, assert in ListResultFinderSpec
that no projection is applied, and drop the sync/rx inconsistency notes
that described the removed behavior.
DisjunctionQuerySpec."Count all dogs or pets with the name Jack" was marked
@PendingFeature for #15789. CountFinder now adds OR criteria through
Query.add(Junction, Criterion), which resolves an association argument to
its identifier the way the AND path always did, so the count is correct
and Spock reported the unexpected pass as a failure. Remove the annotation.
Fixes #15789
---
.../datastore/gorm/mongo/DisjunctionQuerySpec.groovy | 2 --
.../grails/datastore/gorm/finders/ListResultFinder.java | 1 -
.../datastore/gorm/finders/ListResultFinderSpec.groovy | 14 ++++----------
.../org/grails/gorm/rx/finders/RxListResultFinder.groovy | 5 -----
.../grails/gorm/rx/finders/RxListResultFinderSpec.groovy | 2 --
5 files changed, 4 insertions(+), 20 deletions(-)
diff --git a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DisjunctionQuerySpec.groovy b/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DisjunctionQuerySpec.groovy
index 38569b5efc..68ecda3680 100644
--- a/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DisjunctionQuerySpec.groovy
+++ b/grails-data-mongodb/core/src/test/groovy/org/grails/datastore/gorm/mongo/DisjunctionQuerySpec.groovy
@@ -24,7 +24,6 @@ import org.apache.grails.data.testing.tck.domains.PetType
import org.apache.grails.data.mongo.core.GrailsDataMongoTckManager
import org.apache.grails.data.testing.tck.base.GrailsDataTckSpec
import spock.lang.Issue
-import spock.lang.PendingFeature
class DisjunctionQuerySpec extends GrailsDataTckSpec<GrailsDataMongoTckManager> {
def dogType
@@ -65,7 +64,6 @@ class DisjunctionQuerySpec extends GrailsDataTckSpec<GrailsDataMongoTckManager>
pet.name == "Big Bird"
}
- @PendingFeature(reason = "Pre-existing: count over an OR disjunction (countByXOrY) under-counts on MongoDB — the count aggregation does not correctly count distinct matches of the disjunction. Verified pre-existing (MongoQuery count path is unchanged from before the GormRegistry rewrite; find-over-OR works). Tracked for an independent fix in https://github.com/apache/grails-core/issues/15789.")
@Issue('GPMONGODB-380')
void "Count all dogs or pets with the name Jack"() {
given: "Some data"
diff --git a/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/finders/ListResultFinder.java b/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/finders/ListResultFinder.java
index 8fc2751539..3b045f3491 100644
--- a/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/finders/ListResultFinder.java
+++ b/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/finders/ListResultFinder.java
@@ -123,7 +123,6 @@ public class ListResultFinder implements FinderMethod, QueryBuildingFinder {
private Object doInvoke(final DynamicFinderInvocation invocation) {
return FinderSupport.execute(datastoreResolver, (SessionCallback<Object>) session -> {
Query query = buildQuery(invocation, session);
- query.projections().distinct();
return query.list();
});
}
diff --git a/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/finders/ListResultFinderSpec.groovy b/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/finders/ListResultFinderSpec.groovy
index e2888917b3..75642b4c28 100644
--- a/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/finders/ListResultFinderSpec.groovy
+++ b/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/finders/ListResultFinderSpec.groovy
@@ -90,13 +90,11 @@ class ListResultFinderSpec extends Specification {
!finder.isMethodMatch('findAllByName')
}
- void "findAllBy runs the full round trip, applies distinct and returns the full list"() {
+ void "findAllBy runs the full round trip without a distinct projection and returns the full list"() {
given:
List<FinderTestEntity> expected = [new FinderTestEntity(name: 'Bob')]
- Query.ProjectionList projectionList = Mock(Query.ProjectionList)
Query query = Mock(Query) {
getEntity() >> persistentEntity
- projections() >> projectionList
}
Session session = Stub(Session) {
createQuery(FinderTestEntity) >> query
@@ -109,7 +107,7 @@ class ListResultFinderSpec extends Specification {
then:
result.is(expected)
- 1 * projectionList.distinct()
+ 0 * query.projections()
1 * query.list() >> expected
0 * query.singleResult()
}
@@ -119,10 +117,8 @@ class ListResultFinderSpec extends Specification {
// Called reflectively (dynamic Groovy dispatch, not part of FinderMethod) by
// AbstractDetachedCriteria#methodMissing.
List<FinderTestEntity> expected = [new FinderTestEntity(name: 'Bob')]
- Query.ProjectionList projectionList = Mock(Query.ProjectionList)
Query query = Mock(Query) {
getEntity() >> persistentEntity
- projections() >> projectionList
}
Session session = Stub(Session) {
createQuery(FinderTestEntity) >> query
@@ -142,17 +138,15 @@ class ListResultFinderSpec extends Specification {
then:
result.is(expected)
1 * query.add({ it instanceof Query.PropertyCriterion })
- 1 * projectionList.distinct()
+ 0 * query.projections()
1 * query.list() >> expected
}
void "invoke(Class, methodName, DetachedCriteria, Object[]) with a null detachedCriteria never merges anything onto the built query"() {
given:
List<FinderTestEntity> expected = [new FinderTestEntity(name: 'Bob')]
- Query.ProjectionList projectionList = Mock(Query.ProjectionList)
Query query = Mock(Query) {
getEntity() >> persistentEntity
- projections() >> projectionList
}
Session session = Stub(Session) {
createQuery(FinderTestEntity) >> query
@@ -166,7 +160,7 @@ class ListResultFinderSpec extends Specification {
then:
result.is(expected)
0 * query.add({ it instanceof Query.PropertyCriterion })
- 1 * projectionList.distinct()
+ 0 * query.projections()
1 * query.list() >> expected
}
diff --git a/grails-datamapping-rx/src/main/groovy/org/grails/gorm/rx/finders/RxListResultFinder.groovy b/grails-datamapping-rx/src/main/groovy/org/grails/gorm/rx/finders/RxListResultFinder.groovy
index 58e515ec97..219c0f6f25 100644
--- a/grails-datamapping-rx/src/main/groovy/org/grails/gorm/rx/finders/RxListResultFinder.groovy
+++ b/grails-datamapping-rx/src/main/groovy/org/grails/gorm/rx/finders/RxListResultFinder.groovy
@@ -34,11 +34,6 @@ import org.grails.datastore.rx.query.RxQuery
/**
* Implements {@code findAllBy*} and the {@code findAll<booleanProperty>By*} boolean-clause form
* for RxGORM - the rx-module mirror of {@link org.grails.datastore.gorm.finders.ListResultFinder}.
- *
- * <p>Preserved exactly as it existed in the previous per-type rx finder classes: unlike the
- * synchronous {@code ListResultFinder}, this does NOT apply a {@code distinct()} projection - that
- * was already a pre-existing difference between the sync and rx implementations, not something
- * introduced or fixed by this refactor.
*/
@CompileStatic
class RxListResultFinder implements FinderMethod {
diff --git a/grails-datamapping-rx/src/test/groovy/org/grails/gorm/rx/finders/RxListResultFinderSpec.groovy b/grails-datamapping-rx/src/test/groovy/org/grails/gorm/rx/finders/RxListResultFinderSpec.groovy
index 57bb4fb5d3..415c8004b4 100644
--- a/grails-datamapping-rx/src/test/groovy/org/grails/gorm/rx/finders/RxListResultFinderSpec.groovy
+++ b/grails-datamapping-rx/src/test/groovy/org/grails/gorm/rx/finders/RxListResultFinderSpec.groovy
@@ -108,8 +108,6 @@ class RxListResultFinderSpec extends Specification {
1 * query.add({ Query.Criterion it -> it instanceof Query.Junction })
1 * query.findAll() >> observable
0 * query.findAll(_)
- // Unlike the synchronous ListResultFinder, RxListResultFinder never applies a distinct()
- // projection - a pre-existing sync/rx inconsistency this refactor preserves, not fixes.
0 * query.projections()
result.is(observable)
}