Search code examples
neo4jcypherspring-data-neo4jneo4j-ogmspring-data-neo4j-5

Spring Data Neo4j/OGM session query for domain object


I have the following Neo4j SDN5/OGM/Cypher logic:

MATCH (v:Value)-[:CONTAINS]->(hv:HistoryValue) 
WHERE v.id = {valueId} 
OPTIONAL MATCH (hv)-[:CREATED_BY]->(u:User) 
WHERE {fetchCreateUsers} 
WITH u, hv 
ORDER BY hv.createDate DESC 
WITH count(hv) as count, COLLECT({u: u, hv: hv}) AS data 
RETURN REDUCE(s = [], i IN RANGE(0, count - 1, {step}) | s + data[i]) AS result

I execute this query in the following way:

parameters.put("valueId", valueId);
parameters.put("fetchCreateUsers", fetchCreateUsers);
parameters.put("step", step);

StringBuilder cypherQuery = new StringBuilder();
cypherQuery .append(query)); // the query mentioned above

Result queryResult = session.query(cypherQuery.toString(), parameters);

for (Map<String, Object> result : queryResult) {

    Map<String, Object>[] maps = (Map<String, Object>[]) result.get("result");

    for (Map<String, Object> map : maps) {
        System.out.println(map.get("hv").getClass());
        System.out.println(map.get("u"));
    }
}

I expect to receive map.get("hv") as my domain object model - HistoryValue but it is the class of org.neo4j.driver.internal.InternalNode.

Is there any way to get hv and u objects as the instances of my SDN domain model?


Solution

  • Your are querying the database by using a "raw" cypher call: Result queryResult = session.query(cypherQuery.toString(), parameters); This will just return the data in the form the java-driver produces.

    To get a real object mapping you have to use either use the OGM session methods that support user types e.g. Session#load(Class, ID) etc. or create a @Query annotated method in your SpringData Neo4j repository and an additional class @QueryResult annotated in your package that gets scanned for entities. Details in SpringData Neo4j documentation.