0
votes

I really hope this hasn't been asked and my search skills lacking. I am currently learning how spring data interacts with the neo4j stand-alone server via the rest api (spring-data-neo4j-rest) and ran into an interesting issue with iterating a query result.

I started by creating the neo4j project (using an embedded db) found in the book Instant Spring Tool Suite, verifying that it worked, upgrading the project to the most recent release of Spring, verifying that worked and then pointed it at a stand alone server to make the necessary changes.

I'm able to create the nodes in my JUnit test case, but when running a test case against a method with an annotated query, it doesn't seem to be working correctly. I've tried looking for examples and others who may have run into the issue and am convinced it's my relative inexperience that is the main source of the issue.

Here is the query code: @Query( "MATCH (x {name: {0}})<-[role:MEMBER_OF]-(employee) " +"return distinct employee.firstName + ' ' + employee.lastName as name," +"role.title as title") Iterable> findEmployeesAndRolesByProjectName(String prjName);

Here is the test case:

@Transactional
public void shouldReturnEmployeesAndRolesByProject() {
    Project projectX = template.save(new Project("Project X"));
    Project projectY = template.save(new Project("Project Y"));

    Employee johnDoe = template.save(new Employee("John", "Doe"));
    johnDoe.assignedTo(projectX, "Software Engineer");
    johnDoe.assignedTo(projectY, "Business Analyst");
    template.save(johnDoe);
    Employee janeDoe = template.save(new Employee("Jane", "Doe"));
    janeDoe.assignedTo(projectX, "Project Manager");
    template.save(janeDoe);

    Iterable<Map<String, String>> projectRoles = projectRepository
            .findEmployeesAndRolesByProjectName("Project X");

    Map<String, String> role1 = projectRoles.iterator().next();

    System.out.print(role1.get("name") + ' ' + role1.get("title") + '\n');
    assertEquals("John Doe", role1.get("name"));
    assertEquals("Software Engineer", role1.get("title"));

    Map<String, String> role2 = projectRoles.iterator().next();
    System.out.print(role2.get("name") + ' ' + role2.get("title") + '\n');
    assertEquals("Jane Doe", role2.get("name"));
    assertEquals("Project Manager", role2.get("title"));

    Map<String, String> role3 = projectRoles.iterator().next();
    System.out.print(role3.get("name") + ' ' + role3.get("title") + '\n');
    assertEquals("John Doe", role3.get("name"));
    assertEquals("Software Engineer", role3.get("title"));

}

The json response when running the query through a rest client results in the following:

{
columns: [2]
0:  "name"
1:  "title"
-
data: [2]
0:  [2]
0:  "John Doe"
1:  "Software Engineer"
-
1:  [2]
0:  "Jane Doe"
1:  "Project Manager"
-
-
}

When iterating through the Map result it only seems to pull the first json response, causing the test unit to fail since it expects a name of "Jane Doe." I added the prints to see what it was pulling for the data in roles 1 and 2 and in each case "John Doe" and "Software Engineer" were printed. I changed the test to look for the John Doe record in role 2 and added the 3rd iteration expecting it to fail as the result set should only contain two records, but that also returns the John Doe record.

I apologize for the long explanation, however can anyone point me in the right direction to reading the response from the query?

1

1 Answers

0
votes

This is not correct. You are re-creating the iterator which always starts from the beginning.

Map<String, String> role1 = projectRoles.iterator().next();

Do it like this:

Iterator<Map<String, String>> it = projectRoles.iterator()
Map<String, String> role1 = it.next();
Map<String, String> role2 = it.next();
assertFalse(it.hasNext());

P.S: SDN over REST is not an optimized solution, you probably either want to change it to a server extension or stay with the embedded database.

See this for an example: http://inserpio.wordpress.com/2014/04/30/extending-the-neo4j-server-with-spring-data-neo4j/