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);
}