jake
jake

Reputation: 51

Spring Data Neo4j Entity Path mapping

I have a standalone Neo4j database 2.1.6. I started with a web based Spring boot project and added Spring Data Neo4j 3.2.1 Release. I am attempting to map the nodes inside a path. I would like to be able to pull a tree of indeterminate depth and map it into java entities.

this query:

match p=(a:fakea)-[*]->(:fakeb) where a.aId = 1
return p;

returns two paths:

{"start":"http://localhost:8180/db/data/node/593222","nodes":["http://localhost:8180/db/data/node/593222","http://localhost:8180/db/data/node/593223","http://localhost:8180/db/data/node/593224","http://localhost:8180/db/data/node/593225"],"length":3,"relationships":["http://localhost:8180/db/data/relationship/2489542","http://localhost:8180/db/data/relationship/2489543","http://localhost:8180/db/data/relationship/2489544"],"end":"http://localhost:8180/db/data/node/593225"}

{"start":"http://localhost:8180/db/data/node/593222","nodes":["http://localhost:8180/db/data/node/593222","http://localhost:8180/db/data/node/593223","http://localhost:8180/db/data/node/593226","http://localhost:8180/db/data/node/593227"],"length":3,"relationships":["http://localhost:8180/db/data/relationship/2489542","http://localhost:8180/db/data/relationship/2489545","http://localhost:8180/db/data/relationship/2489546"],"end":"http://localhost:8180/db/data/node/593227"}

I have tried mapping it several different ways using information I have found here:

Spring data wth ne04j error...error while retrieving paths

@Query shortestPath return type in Spring Data Neo4j

My current repository:

public interface FakeRepository extends GraphRepository<FakeA> {

@Query("match p=(a:fakea)-[*]->(:fakeb) where a.aId = {0} return p;")
public EntityPath<FakeA, FakeB> getTree(Long aId);

I have also tried creating a common abstract class:

public interface FakeRepository extends GraphRepository<FakeAbs> {

@Query("match p=(a:fakea)-[*]->(:fakeb) where a.aId = {0} return p;")
public EntityPath<FakeAbs, FakeAbs> getTree(Long aId);

I cannot retrieve any useful data. I also cannot find the EndResult class mentioned in the posts I listed. I have also tried wrapping the EntityPath with a Result (in the repo as well).

Result<EntityPath<FakeAbs, FakeAbs>> path = fr.getTree(1l);
EntityPath<FakeAbs, FakeAbs> first = path.iterator().next();
first.endNode();

raises:

Null pointer:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

java.lang.NullPointerException: null
    at org.springframework.data.neo4j.support.path.ConvertingEntityPath.endNode(ConvertingEntityPath.java:112)

I receive similar null pointers when I attempt to examine any other parts of the EntityPath structure (length() for example).

How do I query a tree path structure of varying depth and map the results into the correct Node Entities? I specifically want the nodes contained in the path.

Upvotes: 0

Views: 1165

Answers (1)

Clark Richey
Clark Richey

Reputation: 392

Try this

Instead of what you have now:

public interface FakeRepository extends GraphRepository<FakeA> {

@Query("match p=(a:fakea)-[*]->(:fakeb) where a.aId = {0} return p;")
public EntityPath<FakeA, FakeB> getTree(Long aId);

Use:

public interface FakeRepository extends GraphRepository<FakeA> {

@Query("start p=node{0} match (p)-[*]->(a:fakea) return a;")
public FakeA getTree(FakeA fakeA);

That query will take an instance of FakeA and find the FakeA that it is associated with, assuming in this case that there is only one match. If there can be more than one, change meth method signature to return a Set.

However, I think you are also working too hard and not leveraging Spring Data's built in dynamic finders. I recommend you walk through this nice tutorial: Getting Started With Spring Data and Neo4J

Upvotes: 0

Related Questions