Issue upgrading from Neo4j 2 to 3 using embedded Java API

14 views
Skip to first unread message

Howard Lander

unread,
Aug 19, 2016, 2:25:44 PM8/19/16
to Neo4j
Hi all
Hi all

Thanks in advance for the attention and any suggestions. I hope my explanation of the issue is clear enough.

As noted in the subject line, I'm upgrading my java based project to Version 3 of the embedded API.  Unfortunately, I'm getting the following error:

SEVERE: exception in hasNext: The statement has been closed.

Code is below, but here's the explanation. In order to provide a layer of isolation in between my application code and the database code (in this case Neo4j), I'm using the DAO pattern. I'm assigning the ResourceIterator I'm getting back from the findNodes call to a variable in the user level iterator I'm defining. According to this page (https://neo4j.com/docs/java-reference/current/javadocs/org/neo4j/graphdb/Transaction.html

"All ResourceIterables that where returned from operations executed inside a transaction will be automatically closed when the transaction is committed or rolled back. Note however, that the ResourceIterator should be closed as soon as possible if you don't intend to exhaust the iterator"

That's clear enough and seems to explain why I am getting the exception.  But there has to be some way to return an iterator for later use. At least I hope so.  The other choice that comes to mind would be to store all of the nodes in user memory so my user level interface can iterate through them, and that would be a bit problematic. I'll note that this code (which used to use the GlobalGraphOperations class) worked in Neo4j 2. but maybe that was a bug in Neo4j 2? Note that I have tried not closing the transaction (or even using a transaction at all). 

Any ideas?


Here's the actual source of the problem: It's in my definition of an iterator for the user visible structure representing nodes.

      public boolean hasNext() {
           // Wrap the neo4j iterator
           boolean hasN = false;
           GraphDatabaseService theDB = Neo4jDAOFactory.getTheNetworkDB();
           Transaction tx = theDB.beginTx();
           try {
              hasN = nodeIterator.hasNext();
           } catch (Exception e) {
               // should send this back using the message logs eventually
               this.logger.log (Level.SEVERE, "exception in hasNext: " + e.getMessage(), e);
           } finally {
               tx.close();
           }
           return hasN;
       }

But it doesn't make sense without also looking at:

    public Iterator<NetworkNodeTransferObject>
        getNetworkNodes(String nameSpace, String key, Object value){

        Neo4jNetworkNodeDAOIterator theIterator = null;
        GraphDatabaseService theDB = Neo4jDAOFactory.getTheNetworkDB();
        Transaction tx = theDB.beginTx();
        try {

            Label newLabel = Label.label(nameSpace);
            Iterator<Node> neo4jNodeList = theDB.findNodes(newLabel, key, value);
            theIterator = new Neo4jNetworkNodeDAOIterator();
            theIterator.nodeIterator = neo4jNodeList;
        } catch (Exception e) {
            // should send this back using the message logs eventually
            this.logger.log (Level.SEVERE, "exception in getNetworkNodes: " + e.getMessage(), e);
        } finally {
            tx.close();
        }

        return theIterator;
    }

Thanks
Howard

Michael Hunger

unread,
Aug 19, 2016, 4:13:42 PM8/19/16
to ne...@googlegroups.com
You have to iterate inside the or at least a transaction

Von meinem iPhone gesendet
--
You received this message because you are subscribed to the Google Groups "Neo4j" group.
To unsubscribe from this group and stop receiving emails from it, send an email to neo4j+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Howard Lander

unread,
Aug 19, 2016, 4:30:38 PM8/19/16
to ne...@googlegroups.com

Thanks for the reply.

What's funny is I have an identical piece of code that uses

Iterator<Node> neo4jNodeList = theDB.findNodes(newLabel);

instead of

Iterator<Node> neo4jNodeList = theDB.findNodes(newLabel, key, value);

and it works fine.  Everything else is the same and the getNext code is the same call. So maybe there is something wrong with the second call to findNodes.

Very strange ...

Howard
You received this message because you are subscribed to a topic in the Google Groups "Neo4j" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/neo4j/WCcAv3wZVgM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to neo4j+un...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
Howard Lander
Senior Research Software Developer
Renaissance Computing Institute (RENCI)
The University of North Carolina at Chapel Hill
Duke University
North Carolina State University
100 Europa Drive
Suite 540
Chapel Hill, NC 27517
919-445-9651

Michael Hunger

unread,
Aug 19, 2016, 9:31:19 PM8/19/16
to ne...@googlegroups.com
I think while it is not guaranteed to work in a secondary transaction, the find by label uses a different infrastructure (label scan store) than the index lookup, which has to provide snapshots to consistently read from.

I either recommend to iterate and extract the data within one TX and return DTOs from your DAO directly

Or use Cypher, return scalar values and project them into the DTO

Michael

To unsubscribe from this group and stop receiving emails from it, send an email to neo4j+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to a topic in the Google Groups "Neo4j" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/neo4j/WCcAv3wZVgM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to neo4j+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
Howard Lander
Senior Research Software Developer
Renaissance Computing Institute (RENCI)
The University of North Carolina at Chapel Hill
Duke University
North Carolina State University
100 Europa Drive
Suite 540
Chapel Hill, NC 27517
919-445-9651

--
You received this message because you are subscribed to the Google Groups "Neo4j" group.
To unsubscribe from this group and stop receiving emails from it, send an email to neo4j+unsubscribe@googlegroups.com.

Howard Lander

unread,
Aug 21, 2016, 10:17:52 PM8/21/16
to 'Michael Hunger' via Neo4j

​Hi Michael


Thanks for the advice. Can you say a little more about the idea of using Cypher?  I've never done it, so I'm not quite sure how to get started with it.


I guess I could also just use the findNodes(newLabel) call and filter out what I want myself.  That doesn't seem great though.


Thanks again 

Howard


From: 'Michael Hunger' via Neo4j <ne...@googlegroups.com>
Sent: Friday, August 19, 2016 9:31 PM
To: ne...@googlegroups.com
Subject: Re: [Neo4j] Issue upgrading from Neo4j 2 to 3 using embedded Java API
 
To unsubscribe from this group and all its topics, send an email to neo4j+un...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages