Issue when retrieving result from Neo4JRepository

Hello, I'm having an issue with deserializing a simple query using a Neo4JRepository in an example I wrote.

PersonRepository has the following method signature:

public interface PersonRepository extends Neo4jRepository<Person, String> {
...
    @Query( "MATCH (p:Person{name: $pName})-[:LOCATED_IN]-(a:Address)" +
            "MATCH (p:Person)-[:HAS]-(w:Wealth)" +
            "MATCH (p:Person)-[s:STUDIED_IN]-(o:Organization)" +
            "RETURN p.id AS id, a AS address, w AS wealth, s AS education")
    Collection<PersonDetails> getPersonDetails(@Param("pName") String personName);

The PersonDetails result object looks like this:

@Value
public class PersonDetails {
    String id;
    Address address;
    Wealth wealth;
    Collection<StudiedIn> education;
}

Address and Wealth are entities also annotated as @Value.

StudiedIn Looks like this:

@Value
@RequiredArgsConstructor
@RelationshipProperties
public class StudiedIn {
    @Id
    @GeneratedValue
    private Long id;

    private final String degree;
    private final int year;

    @TargetNode
    private final Organization organization;
}

When I use the method, I get the following error:

2021-03-09 16:31:05.057 DEBUG 15888 --- [nio-8888-exec-3] org.springframework.data.neo4j.cypher    : Executing:
MATCH (p:Person{name : $pName})-[:LOCATED_IN]-(a:Address)MATCH (p:Person)-[:HAS]-(w:Wealth)MATCH (p:Person)-[s:STUDIED_IN]-(o:Organization)RETURN p.id AS id, a AS address, w AS wealth, s AS education
2021-03-09 16:31:05.085  WARN 15888 --- [nio-8888-exec-3] .r.s.Neo4jPersistenceExceptionTranslator : Don't know how to translate exception of type class org.springframework.data.neo4j.core.mapping.NoRootNodeMappingException
2021-03-09 16:31:05.086 DEBUG 15888 --- [nio-8888-exec-3] o.s.web.servlet.DispatcherServlet        : Failed to complete request: org.springframework.data.neo4j.core.mapping.NoRootNodeMappingException: Could not find mappable nodes or relationships inside Record<{id: "0220682345", address: node<165>, wealth: node<164>, education: relationship<292>}> for org.springframework.data.neo4j.core.mapping.DefaultNeo4jPersistentEntity@6c8d8b60

Do I explicitly need to map the result with the type? I understood that was implicit because of the Repository method signature definition. Surely I'm missing something else. Could you help me with this?

Hello, I don't think @RelationshipProperties will apply to projection DTOs.
Can you share the Person entity as well?

Person definition is below. If RelationshipProperties won't work, how can I solve it?

@Value
@Builder
@Node("Person")
public class Person {

    @Id
    @Property("id")
    private final String id;

    @Property("name")
    private final String name;

    @Property("dateOfBirth")
    private final LocalDate dateOfBirth;


    @Relationship(type="LOCATED_IN", direction=Relationship.Direction.OUTGOING)
    private Address preferredAddress;

    @Property("gender")
    private final Gender gender;

    @Property("maritalStatus")
    private final MaritalStatus maritalStatus;

    @Builder.Default
    @Property("languages")
    private final List<String> languages = new ArrayList<>();

    @Relationship(type="HAS", direction=Relationship.Direction.OUTGOING)
    private final Wealth wealth;

    @Builder.Default
    @Relationship(type="STUDIED_IN", direction=Relationship.Direction.OUTGOING)
    private final List<StudiedIn> education = new ArrayList<>();

    @Builder.Default
    @Relationship(type="RELATIVE", direction=Relationship.Direction.OUTGOING)
    private final List<Person> relatives = new ArrayList<>();
}

@florent_biville I think the error might not be related with RelationshipProperties, as even removing its collection from the query and from the result object, I still get the same error:

Failed to complete request: org.springframework.data.neo4j.core.mapping.NoRootNodeMappingException: Could not find mappable nodes or relationships inside Record<{id: "0220687650", address: node<165>, wealth: node<164>}> for org.springframework.data.neo4j.core.mapping.DefaultNeo4jPersistentEntity@3e63bd6b

I'm not entirely sure, but I think you can only create projections based on simple properties, not @relationship-annotated fields. I'll let @gerrit.meier confirm whether that's the problem or not.

It would/should work but the initial problem is not within the projection but the custom query.
Spring Data Neo4j does not know what it should create based on "arbitrary" values that get returned.
We have a section in the documentation about good custom query style Spring Data Neo4j .

The idea of a projection is to get a different (use-case-specific) view on the original entity. That's why some information what the underlying node/entity is is needed.

SDN would also respect the given projection definition for a derived query:

Collection<PersonDetails> findByPersonName(String personName)

This will filter the requested data for the Person to the fields you have defined in the projection class (tip: use just an interface here Spring Data Neo4j). There is currently a limitation that prevents us from also respecting the fields of nested projections but this will hopefully get resolved in the next months.

I will for sure have a look on the RelationshipProperties in projections, because right now I am really unsure what will happen there. But as I said, the problem starts earlier here.

1 Like

@gerrit.meier @gnchark I have the same issue my query is very simple and the projection i am doing is following guidelines given in [Spring Data Neo4j](Spring Data Neo4J Projection) documentation.
My Code:

@Query("MATCH (User {mobile:$mobile})-[CONTACT]-(n:User)-[STEPTAKER]-(s:Step) RETURN n.name AS name s.count AS count")
public List<StepList> findAllStepByMobile(String mobile);
    

interface StepList{
    String getName();
    int getCount();
}

The error:
2021-09-10 10:36:25.180 ERROR 18088 --- [nio-8080-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path threw exception [Request processing failed; nested exception is org.springframework.data.neo4j.core.mapping.NoRootNodeMappingException: Could not find mappable nodes or relationships inside Record<{s.count: 400}> for org.springframework.data.neo4j.core.mapping.DefaultNeo4jPersistentEntity@305b43ca] with root cause

org.springframework.data.neo4j.core.mapping.NoRootNodeMappingException: Could not find mappable nodes or relationships inside Record<{s.count: 400}> for org.springframework.data.neo4j.core.mapping.DefaultNeo4jPersistentEntity@305b43ca