Ibraim
Ibraim

Reputation: 1

How can I fetch entity with specific related objects via Spring Data Neo4j 4

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

Answers (3)

Paulin Amougou
Paulin Amougou

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

Luanne
Luanne

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

fkorn
fkorn

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

Related Questions