4

I am using Neo4J OGM (latest versions) to serialize my data into a Neo4J embedded database.

This works with most of my entities, but as soon as i try to save a treelike structure, it takes forever to save and seems to create thousands of such relations although i am just saving some nodes:

RequestExecutor: 223 - creating new node id: -32715, 14690, [255, 100, 139, 207]
RequestExecutor: 223 - creating new node id: -32718, 14691, [29, 95]
RequestExecutor: 223 - creating new node id: -32721, 14692, [255, 102, 142, 212]
RequestExecutor: 223 - creating new node id: -32724, 14693, [30, 95]
RequestExecutor: 223 - creating new node id: -32727, 14694, [255, 103, 143, 213]
RequestExecutor: 223 - creating new node id: -32730, 14695, [31, 95]
RequestExecutor: 223 - creating new node id: -32733, 14696, [255, 103, 143, 213]
RequestExecutor: 223 - creating new node id: -32736, 14697, [32, 95]

These unwind operations take a long time too (this line is much longer, just an excerpt):

EmbeddedRequest: 152 - Request: UNWIND {rows} as row MATCH (startNode) WHERE ID(startNode) = row.startNodeId WITH row,startNode MATCH (endNode) WHERE ID(endNode) = row.endNodeId MERGE (startNode)-[rel:`hasParentNd`]->(endNode) RETURN row.relRef as ref, ID(rel) as id, {type} as type with params {type=rel, rows=[{startNodeId=33, relRef=-32770, endNodeId=32, props={}}, {startNodeId=34, relRef=-32773, endNodeId=61, props={}}, {startNodeId=35, relRef=-32776, endNodeId=34, props={}}, {startNodeId=36, relRef=-32779, endNodeId=61, props={}}, {startNodeId=37, relRef=-32782, endNodeId=36, props={}}, {startNodeId=38, relRef=-32785, endNodeId=61, props={}}, {startNodeId=39, relRef=-19, endNodeId=14698, props={}}, {startNodeId=40, relRef=-32788, endNodeId=38, props={}}, {startNodeId=41, relRef=-22, endNodeId=39, props={}}, {startNodeId=42, relRef=-32791, endNodeId=61, props={}}, {startNodeId=43, relRef=-25, endNodeId=41,......

The node itself looks like this. The NeoEntity class holds the unique id.

@NodeEntity
public class NeoNode extends NeoEntity implements Node, Node.Op {

    @Property("unique")
    private boolean unique = true;

    @Relationship(type = "hasChildrenNd", direction = Relationship.INCOMING)
    private ArrayList<NeoNode.Op> children = new ArrayList<>();

    @Transient
    private NeoArtifact.Op<?> artifact;

    @Relationship(type = "hasParentNd")
    private Op parent;

    public NeoNode() {}
    ...
}

I have tried all kinds of relationships, but have not come to a solution. Would be very thankful for any idea.


Additional info: If i just let it run, it fills up the heap until it crashes:

Exception in thread "neo4j.Scheduler-1" Exception in thread "Neo4j UDC Timer" java.lang.OutOfMemoryError: Java heap space
Christian Huber
  • 828
  • 1
  • 5
  • 20
  • What is the total number of nodes approx, you have created in the database? – Rajendra Kadam Mar 12 '19 at 04:09
  • Don't think any issue with the query. Try increasing heap size for JVM and Neo4j – Rajendra Kadam Mar 12 '19 at 06:25
  • The count of nodes is not very high, less then 20 approximately. Its not about the amout of data, just about the circular references. I switched to SCHEMA_LOAD_STRATEGY, but this just won't hydrate my members instead of recursing endlessly. – Christian Huber Mar 19 '19 at 05:30

1 Answers1

0

You do not need the hasParentNd relationship type, since all neo4j relationships can be navigated bidirectionally. You should just re-use the hasChildrenNd relationship with the opposite directionality. That will allow the same relationship instance to be navigated bidirectionally (instead of creating a new redundant relationship).

Try changing your code to this:

@NodeEntity 
public class NeoNode extends NeoEntity implements Node, Node.Op { 

    @Property("unique")
    private boolean unique = true;

    @Relationship(type = "hasChildrenNd", direction = Relationship.INCOMING)
    private ArrayList<Op> children = new ArrayList<>();

    @Transient 
    private NeoArtifact.Op<?> artifact; 

    @Relationship(type = "hasChildrenNd", direction = Relationship.OUTGOING)
    private Op parent;

    public NeoNode() {} 
    ... 
} 

Aside: The hasChildrenNd type name seems confusing, since an outgoing hasChildrenNd relationship points to a parent instead of a child.

cybersam
  • 63,203
  • 6
  • 53
  • 76
  • I fear that did not help. I tried to revert to SCHEMA_LOAD_STRATEGY, but instead of recursing endlessly, it does not load half of the schema, including the treelike structure i defined above. – Christian Huber Mar 19 '19 at 05:28