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
This commit is contained in:
Gerrit Meier
2023-06-19 15:59:39 +02:00
parent 507b0fe756
commit 6decfa833e
3 changed files with 12 additions and 1 deletions

View File

@@ -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<PropertyFilter.RelaxedPropertyPath> 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<PropertyFilter.RelaxedPropertyPath> 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<SortItem> orderBy) {

View File

@@ -338,6 +338,7 @@ public final class QueryFragmentsAndParameters {
} else {
queryFragments.setReturnExpressions(
cypherGenerator.createReturnStatementForMatch(entityMetaData, includeField));
queryFragments.setProjectingPropertyFilter(includeField);
}
if (pageable != null) {

View File

@@ -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;