SpringDataNeo4j-4:在“所有者”类表示策略中的集合中存储实体(拥有的项)

时间:2015-12-07 12:36:21

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

不幸的是,但是没有足够的信息,以及演示在Java相关实体中表示的最佳方式的示例,如“所有者 - 拥有的项目”。

我不是在谈论neo4j关系方向,而只是关于保存这些实体时的java数据表示和持久性行为。 Here指南讨论了持久性深度:

  

“...另请注意,此行为不依赖于任何已配置的行为   关于注释的关系方向。这是Java的问题   引用,与数据库中的数据模型无关。“

我想了解在我的数据模型中选择什么策略。所以......

例如,我有一个类“Task”,它可以有许多子任务(相同类型)。任何任务都可以由“项目”拥有,并且可以是某个“组件”的成员......尽管如此,任务可以直接由项目拥有,并且根本不能与组件链接。

选项1:

public class Project {

 @Relationship(type = "HAS_TASK", direction = Relationship.OUTGOING)
 private Set<Task> tasks = new HashSet<>();

 @Relationship(type = "HAS_COMPONENT", direction = Relationship.OUTGOING)
 private Set<Component> components = new HashSet<>();


}

public class Component {

 @Relationship(type = "HAS_TASK", direction = Relationship.OUTGOING)
 private Set<Task> tasks = new HashSet<>();                

}

public class Task {

 @Relationship(type = "HAS_SUBTASK", direction = Relationship.OUTGOING)
 Set<Task> subtasks = new HashSet<>();

}

这似乎是最合乎逻辑的数据表示。但似乎有缺点:

  • 当创建新任务并调用template.save(newTask)时,只会保留新的Task对象并在此Task和Project之间创建关系, - 应该提取Project项目并使用new更新将Task保存为集合元素。 所以,实际上,我们甚至不需要保存单独的Task对象。我们可以立即提取Project对象,将Task添加到集合中并更新Project ...这对我来说很奇怪......

  • 当我们创建Task对象时,我们可以假设,然后Project甚至根本不存在,如果是这样 - 它不会被递归创建,因为Task对项目一无所知......

选项2:

public class Project { }

public class Component {

 private Project project;   

}


public class Task {

 private Task parentTask: // can be null

 private Component component; // can be null

 private Project project; // can be null

}

此模型允许创建新任务或新组件设置从db(或设置新项目)中提取现有项目并保存它们......我们确定,父对象将持久存在以及子项。

Вrawbacks:

  • 在db ...中看起来像“FOREIGN_KEY”链接...

  • 我们有冗余的“空”属性,例如,如果任务没有与某个项目或组件链接......

所以,我不知道该选择什么 - 两种解决方案都可行......但它不是关于工作,而是关于“清洁代码”

1 个答案:

答案 0 :(得分:0)

一般准则是您的对象模型尽可能贴近底层图。

在图表中,任务,项目和组件通过关系连接,因此对象模型代表的是什么。

选项2看起来比选项1更接近您的图表模型,后者限制了导航性。

此博客文章有助于更好地解释这一点:http://graphaware.com/neo4j/2015/09/03/sdn-4-object-model.html