From 369bbe0ccdbc87868be7893f6fddae0657ad90fb Mon Sep 17 00:00:00 2001 From: Gerrit Meier Date: Thu, 24 Oct 2019 09:58:17 +0200 Subject: [PATCH] Prevent null values from getting into the parameter lists. According to https://neo4j.com/docs/cypher-manual/current/syntax/working-with-null/#cypher-null-intro the result will always be empty since null != null. Warn the user that the parameter value is not suitable for the query but don't suppress its execution. It might get called via user's input values or similar. --- .../data/repository/query/Neo4jQuerySupport.java | 15 +++++++++++++++ .../data/integration/imperative/RepositoryIT.java | 6 ++++++ 2 files changed, 21 insertions(+) diff --git a/spring-data-neo4j/src/main/java/org/neo4j/springframework/data/repository/query/Neo4jQuerySupport.java b/spring-data-neo4j/src/main/java/org/neo4j/springframework/data/repository/query/Neo4jQuerySupport.java index 3059d956f..4d9fd91b7 100644 --- a/spring-data-neo4j/src/main/java/org/neo4j/springframework/data/repository/query/Neo4jQuerySupport.java +++ b/spring-data-neo4j/src/main/java/org/neo4j/springframework/data/repository/query/Neo4jQuerySupport.java @@ -26,11 +26,14 @@ import java.util.List; import java.util.Map; import java.util.function.BiFunction; +import org.apache.commons.logging.LogFactory; import org.neo4j.driver.Record; +import org.neo4j.driver.Values; import org.neo4j.driver.types.TypeSystem; import org.neo4j.springframework.data.core.convert.Neo4jSimpleTypes; import org.neo4j.springframework.data.core.mapping.Neo4jMappingContext; import org.neo4j.springframework.data.repository.query.Neo4jQueryMethod.Neo4jParameters; +import org.springframework.core.log.LogAccessor; import org.springframework.data.domain.Range; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; @@ -54,6 +57,8 @@ abstract class Neo4jQuerySupport { protected final Neo4jQueryMethod queryMethod; protected final Class domainType; + private static final LogAccessor log = new LogAccessor(LogFactory.getLog(Neo4jQuerySupport.class)); + Neo4jQuerySupport(Neo4jMappingContext mappingContext, Neo4jQueryMethod queryMethod) { Assert.notNull(mappingContext, "The mapping context is required."); @@ -111,6 +116,16 @@ abstract class Neo4jQuerySupport { */ final Object convertParameter(Object parameter) { + if (parameter == null) { + // According to https://neo4j.com/docs/cypher-manual/current/syntax/working-with-null/#cypher-null-intro + // it does not make any sense to continue if a `null` value gets into a comparison + // but we just warn the users and do not throw an exception on `null`. + log.warn("Do not use `null` as a property value for comparison." + + " It will always be false and return an empty result."); + + return Values.NULL; + } + // Maybe move all of those into Neo4jConverter at some point. if (parameter instanceof Range) { return convertRange((Range) parameter); diff --git a/spring-data-neo4j/src/test/java/org/neo4j/springframework/data/integration/imperative/RepositoryIT.java b/spring-data-neo4j/src/test/java/org/neo4j/springframework/data/integration/imperative/RepositoryIT.java index 49437ee34..715df0171 100644 --- a/spring-data-neo4j/src/test/java/org/neo4j/springframework/data/integration/imperative/RepositoryIT.java +++ b/spring-data-neo4j/src/test/java/org/neo4j/springframework/data/integration/imperative/RepositoryIT.java @@ -1198,6 +1198,12 @@ class RepositoryIT { .contains(person1); } + @Test + void findBySimplePropertyByEqualsWithNullShouldWork() { + int emptyResultSize = 0; + assertThat(repository.findAllBySameValue(null)).hasSize(emptyResultSize); + } + @Test void findBySimplePropertiesAnded() {