From 6decfa833e2c82313cf7c8f183399f275b5774c1 Mon Sep 17 00:00:00 2001 From: Gerrit Meier Date: Mon, 19 Jun 2023 15:59:39 +0200 Subject: [PATCH] GH-2748 - Fix property filter in `FluentQuery...`. Using FluentQueryByExample/Predicate with a subset of properties, the underlying fetching mechanics in the Neo4jTemplate was still querying for everything if the domain has a potential circular dependency. Closes #2748 --- .../data/neo4j/repository/query/QueryFragments.java | 9 ++++++++- .../repository/query/QueryFragmentsAndParameters.java | 1 + .../data/neo4j/integration/shared/common/Flight.java | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/neo4j/repository/query/QueryFragments.java b/src/main/java/org/springframework/data/neo4j/repository/query/QueryFragments.java index ae90c2b10..c84ccbc0c 100644 --- a/src/main/java/org/springframework/data/neo4j/repository/query/QueryFragments.java +++ b/src/main/java/org/springframework/data/neo4j/repository/query/QueryFragments.java @@ -21,6 +21,7 @@ import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Predicate; import org.apiguardian.api.API; import org.neo4j.cypherdsl.core.Condition; @@ -61,6 +62,7 @@ public final class QueryFragments { * This flag becomes {@literal true} for backward scrolling keyset pagination. Any {@code AbstractNeo4jQuery} will in turn reverse the result list. */ private boolean requiresReverseSort = false; + private Predicate projectingPropertyFilter; public void addMatchOn(PatternElement match) { this.matchOn.add(match); @@ -95,8 +97,13 @@ public final class QueryFragments { this.scalarValueReturn = isScalarValue; } + public void setProjectingPropertyFilter(Predicate projectingPropertyFilter) { + this.projectingPropertyFilter = projectingPropertyFilter; + } + public boolean includeField(PropertyFilter.RelaxedPropertyPath fieldName) { - return this.returnTuple == null || this.returnTuple.include(fieldName); + return (projectingPropertyFilter == null || projectingPropertyFilter.test(fieldName)) + && (this.returnTuple == null || this.returnTuple.include(fieldName)); } public void setOrderBy(Collection orderBy) { diff --git a/src/main/java/org/springframework/data/neo4j/repository/query/QueryFragmentsAndParameters.java b/src/main/java/org/springframework/data/neo4j/repository/query/QueryFragmentsAndParameters.java index 7d837500e..c80ed3071 100644 --- a/src/main/java/org/springframework/data/neo4j/repository/query/QueryFragmentsAndParameters.java +++ b/src/main/java/org/springframework/data/neo4j/repository/query/QueryFragmentsAndParameters.java @@ -338,6 +338,7 @@ public final class QueryFragmentsAndParameters { } else { queryFragments.setReturnExpressions( cypherGenerator.createReturnStatementForMatch(entityMetaData, includeField)); + queryFragments.setProjectingPropertyFilter(includeField); } if (pageable != null) { diff --git a/src/test/java/org/springframework/data/neo4j/integration/shared/common/Flight.java b/src/test/java/org/springframework/data/neo4j/integration/shared/common/Flight.java index ef8ff2eb1..57ba60f18 100644 --- a/src/test/java/org/springframework/data/neo4j/integration/shared/common/Flight.java +++ b/src/test/java/org/springframework/data/neo4j/integration/shared/common/Flight.java @@ -36,6 +36,9 @@ public class Flight { @Relationship(type = "ARRIVES") private final Airport arrival; + @Relationship("NEXT_FLIGHT") + private Flight nextFlight; + public Flight(String name, Airport departure, Airport arrival) { this.name = name; this.departure = departure;