0

Unfortunately, but there is not enough information, as well as examples which demonstrates the best way to represent in Java related entities like "OWNER - OWNED ITEMS".

I'm not talking about neo4j relationship direction, but only about java data representation and persistence behaviour while saving such entities. Here guide talks about persistence depth:

"...Also note that this behaviour is not dependent on any configured relationship direction on the annotations. It is a matter of Java references and is not related to the data model in the database."

I want to understand what strategy to choose in my data model. So...

For example, I have a class "Task" which can have many subtasks(of a same type). Any Task can be owned by "Project" and can be a member of some "Component"... Despite that, a Task can be owned by Project directly, and can be not linked with Component at all.

Option 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<>();

}

This seems the most logical data representation. But seems to have drawbacks:

  • When the new Task is created and template.save(newTask) is called, then only new Task object will be persisted and to create relationship between this Task and Project, - Project object should be extracted and updated with new saved Task as collection element. So, actually, we don't even need to save separate Task object. We can at once extract Project object, add Task to collection and update Project...It looks weird to me...

  • When we create Task object, we can assume, then Project even can not exist at all and if so - it will not be created recursively, becouse Task doesn't know anything about Project...

Option 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

}

This model allows creating new Tasks or new Components setting extracted existing Project from db (or setting new Project) and saving them both...And we certain, that the parent object will be persisted as well as a child.

Вrawbacks:

  • it looks like "FOREIGN_KEY" links in relation db...

  • We have redundant "null" properties, if the Task, for example, doesn't linked with some Project or Component...

So, I don't know what to choose - both solution will work...but it is not about working, but about "clean code"

Luanne
  • 19,145
  • 1
  • 39
  • 51
maret
  • 1,826
  • 1
  • 13
  • 18

1 Answers1

0

The general guideline is that your object model maps as closely as possible to the underlying graph.

In the graph, Tasks, Projects and Components are connected via relationships, so that's what the object model represents.

Option 2 looks closer to your graph model than Option 1 which limits navigability.

This blog post helps explain this better: http://graphaware.com/neo4j/2015/09/03/sdn-4-object-model.html

Luanne
  • 19,145
  • 1
  • 39
  • 51
  • Thanks! Already read it). So, suppose then I've stucked with a second one... Have a one more question, why a first one " limits navigability"? Will be grateful for the explanation. – maret Dec 07 '15 at 15:32
  • It does look like the most logical one, not sure that being stuck with it is a bad thing ;-) You could go with option 1 of course and manage how you save the entities based on what they're connected to- this looks like more code to manage – Luanne Dec 07 '15 at 15:35
  • Thanks! Then Option 2...So be it) – maret Dec 07 '15 at 15:37