3

I have a problem when I try to retrieve two nodes with the same label (the same type) and a relathioship between both whit spring data.

enter image description here

I did a query for get the last one, like that:

 @Query("MATCH (b1:Block)-[rel]->(b2) " +
        "WHERE NOT (b1)<-[]-() " +
        "RETURN *; ")
Block findLast();

And the Block attributes are:

 @GraphId
    private Long id;

    private String hash;

    @Relationship(direction = Relationship.OUTGOING)
    private Block predecessor;

The problem is that the ogm says that there is two results (I supose b1 and b2), and throw this exception:

Caused by: java.lang.RuntimeException: Result not of expected size. Expected 1 row but found 2
    at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.queryForObject(ExecuteQueriesDelegate.java:73) ~[neo4j-ogm-core-2.1.5.jar:na]
    at org.neo4j.ogm.session.Neo4jSession.queryForObject(Neo4jSession.java:382) ~[neo4j-ogm-core-2.1.5.jar:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121]

I understand that the OGM can not choise what node is returned in the @Query method, because find two nodes of the same type, but how can I fill the second one into the first one??

Thanks!!!!

Xavi Torrens
  • 337
  • 1
  • 12
  • Can you be more specific? What do you mean by "fill the second one into the first one"? Also, your Cypher query does not specify any particular order on the returned rows, so "first" and "second" don't really mean anything. – cybersam Jan 27 '18 at 01:03
  • I edited the last message. I added the node attributes. I need to fill the attribute _predecessor_ of the node AAD3hn with the node AAbq1D (as you can see in the top picture). The function findLast() should be return the node AAD3hn. In one hand that fails, because the query return two nodes and the findLast() function return only one node (not a list), in the other hand I can not remove the node AAbq1D from the query result because I need to fill it in the other node. – Xavi Torrens Jan 27 '18 at 04:23

1 Answers1

0

Your interpretation of OGMs behaviour in this case with a custom query is right. There is no chance for OGM to distinguish between the two Block entities.

I do think the only option you have here is to introduce a @QueryResult class and return an instance of it instead of a Block object.

@QueryResult
public class BlockResult {
     private Block predecessor;
    /* other fields and/or relationships */
}

This class needs to live in the package(s) for entity scans. Then you could change your annotated query method to something like:

@Query("MATCH (b1:Block)-[rel]->(b2) " +
    "WHERE NOT (b1)<-[]-() " +
    "RETURN b1, rel, b2 as predecessor; ")
Block findLast();

The important bit here is the as predecessor part because SDN needs to know the 'column' name in the result to match it in the QueryResult object.

meistermeier
  • 7,942
  • 2
  • 36
  • 45