如何通过Spring Data Neo4j 4获取具有特定相关对象的实体

时间:2016-03-29 13:34:09

标签: neo4j spring-data-neo4j-4 neo4j-ogm

我有以下(项目,用户,任务)域对象。如何通过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;
}

3 个答案:

答案 0 :(得分:1)

您可以使用Neo4jTemplate.query和自定义查询来检索结果。在这种情况下,n将是一个已填充了属性和任务的项目。 ID函数可以获取节点的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");
}

答案 1 :(得分:1)

SDN 4不支持加载具有某种关系的实体 - 它是无(深度0)或全部(深度n,默认深度1)。

因此,如果加载具有默认深度1的项目,它将加载项目的属性,相关任务和用户的属性,但不加载它们的关系。

如果您只需要实体ID,那么正如@fkorn所回答的那样,自定义查询是最佳选择

答案 2 :(得分:0)

您还可以使用Repository并使用@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);
}