0

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;
}

3 Answers 3

1

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");
}
Sign up to request clarification or add additional context in comments.

Comments

1

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

1 Comment

can I load a certain attribute using SDN5 or there is no other way ? stackoverflow.com/questions/49814386/… here is the detail question please have a look
0

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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.