Mihai Raulea
Mihai Raulea

Reputation: 438

Unable to delete nodes while traversing the graph - neo4j java embedded api

I am using this traversal to get all nodes i want to delete. I do the traversal, and keep the nodes in a separate structure, not to break the traversal. Then i iterate over the separate structures, deleting all relationships, all relationships attached to the nodes(so i can delete safely the nodes), and finally all the nodes. I don't get any exceptions raised, the delete seems to work. I properly finish the transaction and shut down the database. But when i re-run the code, i see the nodes and relationships are still there. I have tried 2 separate transactions, marking nodes and rels with a "delete" property, and then in a separate transaction tried deleting them. Nothing seems to work. Any ideas?

public synchronized void cleanDatabase()
{
    Transaction tx = null;
    try 
    {
        tx = service.beginTx();
        ResourceIterator<Node> restaurants = service.findNodesByLabelAndProperty(DynamicLabel.label("Restaurant"), "name", "restaurant").iterator();//GlobalGraphOperations.at(service).getAllNodesWithLabel(DynamicLabel.label("Restaurant")).iterator();//
        Node restaurantNode = null;

        Set<Relationship> removableRelations = new HashSet<Relationship>();
        Set<Node> removableNodes = new HashSet<Node>();

        while(restaurants.hasNext())
        {
            TraversalDescription td = service.traversalDescription()
                    .uniqueness( Uniqueness.NODE_GLOBAL)
                    .breadthFirst()             
                    .relationships(AllRelationshipTypes.hasAgents, Direction.OUTGOING)
                    .relationships(AllRelationshipTypes.hasClients, Direction.OUTGOING)
                    //etc

            restaurantNode = restaurants.next();
            Traverser results = td.traverse( restaurantNode );
            ResourceIterator<Node> nodeIt = results.nodes().iterator();
            int nodeCount = 0;

            while(nodeIt.hasNext())
            {
                nodeCount++;
                Node node = nodeIt.next();
                removableNodes.add(node);
                Iterator<Relationship> relIt = node.getRelationships().iterator();
                while(relIt.hasNext())
                {
                    Relationship rel = relIt.next();
                    removableRelations.add(rel);
                }
            }

            System.out.println("have found "+nodeCount);

        }

        //System.out.println(uniqueRels.toString());

        for(Relationship removableRel:removableRelations){
            //removableRel.setProperty("delete", true);
            removableRel.delete();
            //System.out.println(removableRel.toString());
        }
        int otherNodeCount = 0;
        for(Node remNode:removableNodes){

            Iterator<Relationship> relsAttached = remNode.getRelationships().iterator();
            while(relsAttached.hasNext())
            {
                Relationship relAttach = relsAttached.next();                   
                //relAttach.setProperty("delete", true);
                relAttach.delete();
            }           
            //remNode.setProperty("delete", true);
            remNode.delete();
            System.out.println(remNode.getLabels().toString());

            otherNodeCount++;
        }
        System.out.println(otherNodeCount+" other node count");
        System.out.println("done");
        tx.success();
        System.out.println("success");
    }
    catch(Exception e)
    {
        System.out.println("exception");
        System.out.println(e.getMessage());
        tx.failure();
    }
}

Upvotes: 2

Views: 635

Answers (1)

Doodad
Doodad

Reputation: 1518

It seems you are not calling tx.finish() or tx.close(), nor using a try-with-resources (that calls close() automatically in newer versions).

What version of neo4j are you using?

If it has a close() method, you have to call it in the finally, no matter if the transaction fails or not.

If it doesn't have a close() method, then you have to call finish(). Both should do the same thing.

The catch though is that when you use try-with-resources (Java 7+) to create the transaction, it implements the java.lang.AutoCloseable, so you don't need the close() method.

Upvotes: 3

Related Questions