Reputation: 1
I have the following (Project, User, Task) domain objects. How can I fetch entity with specific related objects via Spring Data Neo4j 4 (SDN4)? For example I want to fetch a project with related tasks, but without users. This sample doesn't work. Defining depth
in neo4jTemplate.load
method is not appropriate for me, because it gets user objects.
public Project findProjectWithTasks(Long projectId){
Project project = neo4jTemplate.load(Project.class, projectId, 0);
/*
project.id <- correct
project.name <- correct
project.tasks <- null, but in previous versions of Spring Data Neo4j I had empty entities with id
*/
Collection<Task> tasks = neo4jTemplate.loadAll(project.getTasks()); // <- returns null, because project.getTasks() is null
return project;
}
//----------
@NodeEntity
class Project {
@GraphId
private Long id;
private String name;
@Relationship(direction = Relationship.OUTGOING, type = "PROJECT_TASK")
private Set<Task> tasks;
@Relationship(direction = Relationship.OUTGOING, type = "PROJECT_USER")
private Set<User> users;
}
@NodeEntity
class Task {
@GraphId
private Long id;
private String name;
@Relationship(direction = Relationship.INCOMING, type = "PROJECT_TASK")
private Project project;
@Relationship(direction = Relationship.OUTGOING, type = "TASK_USER_ASSIGNED")
private User assignedTo;
}
@NodeEntity
class User {
@GraphId
private Long id;
private String email;
@Relationship(direction = Relationship.INCOMING, type = "TASK_USER_ASSIGNED")
private Set<Task> tasks;
@Relationship(direction = Relationship.INCOMING, type = "PROJECT_USER")
private Set<Project> projects;
}
Upvotes: 0
Views: 657
Reputation: 139
You can also used Repository and achieve the same result with @Query
annotations
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
public interface ProjectRepository extends Neo4jRepository<Project, Long>{
@Query("MATCH (n:Project) " +
"WHERE ID(n) = {0} " +
"WITH n " +
"MATCH p=(n)-[:PROJECT_TASK*0..1]-(m:Task) RETURN p")
public Project findProjectWithTasks(long projectId);
}
Upvotes: 0
Reputation: 19373
SDN 4 does not support loading entities with some relations- it is none (depth 0) or all (depth n, default depth 1).
So if you load a Project with the default depth 1, it will load properties of the Project, properties of related tasks and users, but not their relationships.
If you require entity ID's only, then as answered by @fkorn, a custom query is the way to go
Upvotes: 1
Reputation: 50
You can use Neo4jTemplate.query and a custom Query to retrieve the Result. In this case n will be a Project that's been populated with properties and the Tasks. The ID function gets you the id of a node.
public Project findProjectWithTasks(Long projectId){
String query = "MATCH (n:Project)-[r:PROJECT_TASK]->(m) WHERE ID(n) = {id} RETURN n,r,m";
Map<String,Object> map = new HashMap<>();
map.put(id,projectId);
Result result = neo4jTemplate.query(query,map);
return (Project) result.iterator().next().get("n");
}
Upvotes: 1