Как я могу получить объект с определенными связанными объектами через Spring Data Neo4j 4

У меня есть следующие объекты домена (Project, User, Task). Как я могу получить объект с определенными связанными объектами через Spring Data Neo4j 4 (SDN4)? Например, я хочу получить проект со связанными задачами, но без пользователей. Этот образец не работает. Определение depth в методе neo4jTemplate.load мне не подходит, потому что он получает пользовательские объекты.

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

person Ibraim    schedule 29.03.2016    source источник


Ответы (3)


Вы можете использовать Neo4jTemplate.query и пользовательский запрос для получения результата. В этом случае n будет проектом, заполненным свойствами и задачами. Функция ID дает вам идентификатор узла.

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");
}
person fkorn    schedule 29.03.2016

SDN 4 не поддерживает загрузку сущностей с некоторыми отношениями — ни одного (глубина 0) или всех (глубина n, глубина по умолчанию 1).

Поэтому, если вы загрузите проект с глубиной по умолчанию 1, он загрузит свойства проекта, свойства связанных задач и пользователей, но не их отношения.

Если вам требуются только идентификаторы объектов, то, как ответил @fkorn, пользовательский запрос - это путь.

person Luanne    schedule 30.03.2016
comment
Могу ли я загрузить определенный атрибут с помощью SDN5 или нет другого способа? stackoverflow.com/questions/49814386 / вот подробный вопрос, пожалуйста, посмотрите - person Abdullah Al Noman; 13.04.2018

Вы также можете использовать репозиторий и добиться того же результата с аннотациями @Query

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);
}
person Paulin Amougou    schedule 09.05.2018