Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
03-09-2021 01:43 PM
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?
03-10-2021 02:33 AM
Hello, I don't think @RelationshipProperties
will apply to projection DTOs.
Can you share the Person
entity as well?
03-10-2021 04:56 AM
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<>();
}
03-10-2021 05:06 AM
@florent.biville1 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
03-10-2021 05:38 AM
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.
03-10-2021 09:20 AM
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.
09-09-2021 11:06 PM
@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
06-30-2022 08:00 AM
Hi team,
is there any solution for this issue as i have the same issue?
Thanks,
Radhakrishna.
10-26-2022 01:47 AM - edited 10-26-2022 01:47 AM
Hi, I'm also running into the same problem.
Specifically, I have defined an interface-based projection to retrieve a view of a persisted entity from the database through a custom query. However, when I try to run the query from the backend, I get the following error:
org.springframework.data.neo4j.core.mapping.NoRootNodeMappingException: Could not find mappable nodes or relationships inside Record <{name: "Sara", age: 27, sex: "M", occupation: "Worker"}> for org.springframework.data.neo4j.core.mapping.DefaultNeo4jPersistentEntity@30aec673
Here is my custom query (inside a Neo4j Spring repository with root entity Student):
@Query("MATCH (students:Students)-[:LIKES]->()<-[:TEACHES]-(teacher: Teacher {email : $email}) "
+ "WHERE NOT (teacher)-->(students) "
+ "RETURN DISTINCT students.name, students.age, students.sex, students.occupation")
List<StudentCandidate> findUnmetLikingStudents(String email);
here is my StudentCandidate (the projection interface):
public interface StudentCandidate {
String getName();
int getAge();
String getSex();
String getOccupation();
}
and here's my Student class (with most details edited out for brevity's sake):
@Node
public class Student extends Person implements Positionable {
@Id
private String id;
private double latitude;
private double longitude;
private int maxDistance;
private Sex roommateSex;
private int roommateAge;
public Student(String username, String password, boolean enabled, boolean accountNonExpired,
boolean credentialsNonExpired, boolean accountNonLocked, String email, String name, int age,
String sex, String occupation, double latitude, double longitude, int maxDistance, String roommateSex, int roommateAge) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked,
new HashSet<>(Arrays.asList(new UserAuthority(UserRole.STUDENT))), email, name, age, sex,
occupation);
id = UUID.randomUUID().toString();
this.latitude = latitude;
this.longitude = longitude;
this.maxDistance = maxDistance;
this.setRoommateSex(roommateSex);
this.roommateAge = roommateAge;
}
as you may see, some properties (including those in the interface projection) are actually set in the Person superclass. I don't know if that's relevant.
Is there something I'm doing wrong or is this functionality not actually supported?
All the sessions of the conference are now available online