From f351b90b3cb82e63fd25abfc421c0571500578b7 Mon Sep 17 00:00:00 2001 From: Gerrit Meier Date: Fri, 15 Jun 2018 14:09:46 +0200 Subject: [PATCH] DATAGRAPH-1091: Deep nested derived queries support. Introduce feature to support deeper than just one level of property path in derived query methods. (cherry picked from commit dd2ee88) --- pom.xml | 2 +- .../query/derived/builder/FilterBuilder.java | 29 +++++++++++++++---- .../movies/repo/CinemaRepository.java | 2 ++ .../data/neo4j/queries/DerivedQueryTests.java | 14 +++++++++ .../repository/sample/UserRepository.java | 3 +- 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index a47f736b7..b92990089 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ multi spring-data-neo4j - 3.0.3 + 3.0.4-SNAPSHOT 2.0.9.BUILD-SNAPSHOT 1.8 diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/derived/builder/FilterBuilder.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/derived/builder/FilterBuilder.java index 686d51e88..141962ccd 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/derived/builder/FilterBuilder.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/derived/builder/FilterBuilder.java @@ -13,16 +13,19 @@ package org.springframework.data.neo4j.repository.query.derived.builder; +import java.util.ArrayList; import java.util.List; import java.util.Stack; import org.neo4j.ogm.cypher.BooleanOperator; import org.neo4j.ogm.cypher.Filter; +import org.springframework.data.mapping.PropertyPath; import org.springframework.data.repository.query.parser.Part; /** * @author Jasper Blues * @author Nicolas Mervaillie + * @author Gerrit Meier */ public abstract class FilterBuilder { @@ -47,12 +50,28 @@ public abstract class FilterBuilder { } void setNestedAttributes(Part part, Filter filter) { - if (part.getProperty().next() != null) { - filter.setOwnerEntityType(part.getProperty().getOwningType().getType()); - filter.setNestedPropertyType(part.getProperty().getType()); - filter.setPropertyName(part.getProperty().getLeafProperty().getSegment()); - filter.setNestedPropertyName(part.getProperty().getSegment()); + List segments = new ArrayList<>(); + PropertyPath property = part.getProperty(); + if (property.hasNext()) { + filter.setOwnerEntityType(property.getOwningType().getType()); + segments.add(new Filter.NestedPathSegment(property.getSegment(), property.getType())); + segments.addAll(deepNestedProperty(property)); + filter.setPropertyName(property.getLeafProperty().getSegment()); + filter.setNestedPath(segments.toArray(new Filter.NestedPathSegment[0])); } + + } + + private List deepNestedProperty(PropertyPath path) { + List segments = new ArrayList<>(); + if (path.hasNext()) { + PropertyPath next = path.next(); + if (!next.equals(next.getLeafProperty())) { + segments.add(new Filter.NestedPathSegment(next.getSegment(), next.getType())); + segments.addAll(deepNestedProperty(next)); + } + } + return segments; } } diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/examples/movies/repo/CinemaRepository.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/examples/movies/repo/CinemaRepository.java index 92acae249..f1e1ae479 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/examples/movies/repo/CinemaRepository.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/examples/movies/repo/CinemaRepository.java @@ -57,6 +57,8 @@ public interface CinemaRepository extends Neo4jRepository { List findByVisitedName(String name); + List findByVisitedInterestedName(String title); + List findByLocationAndVisitedName(String location, String name); List findByLocationAndCapacityGreaterThan(String location, int capacity); diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/queries/DerivedQueryTests.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/queries/DerivedQueryTests.java index ed3ae56da..e5735c374 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/queries/DerivedQueryTests.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/queries/DerivedQueryTests.java @@ -309,6 +309,20 @@ public class DerivedQueryTests extends MultiDriverTestClass { assertTrue(theatres.contains(new Cinema("Ritzy"))); } + /** + * @see DATAGRAPH-??? + */ + @Test + public void shouldFindNodeEntititiesWithDeepNestedProperty() { + executeUpdate("CREATE (r:Theatre {name:'Ritzy', city:'London', capacity: 7500})" + + " CREATE (u:User {name:'Michal'}) CREATE (u)-[:VISITED]->(r) CREATE (m1:Movie {name:'Speed'})" + + " CREATE (g:Genre {name:'Thriller'}) CREATE (u)-[:INTERESTED]->(g)"); + + List theatres = cinemaRepository.findByVisitedInterestedName("Thriller"); + assertEquals(1, theatres.size()); + assertTrue(theatres.contains(new Cinema("Ritzy"))); + } + /** * @see DATAGRAPH-629 */ diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/sample/UserRepository.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/sample/UserRepository.java index 3d84bcf5d..069901780 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/sample/UserRepository.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/sample/UserRepository.java @@ -19,6 +19,7 @@ import org.springframework.data.neo4j.annotation.Query; import org.springframework.data.neo4j.domain.sample.User; import org.springframework.data.neo4j.repository.Neo4jRepository; import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; @@ -71,5 +72,5 @@ public interface UserRepository extends Neo4jRepository { */ @Query("MATCH (n:User{emailAddress:{emailAddress}}) return n") @Transactional(readOnly = true) - User findByAnnotatedQuery(String emailAddress); + User findByAnnotatedQuery(@Param("emailAddress") String emailAddress); }