cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

How to use org.neo4j.driver.Session properly for subsequent queries?

I'm using neo4j-migrations, which allows JavaBasedMigrations, based on org.neo4j.driver.Session .

(OpenJDK 11, Quarkus 2.7.2, Neo4j 4.4.4, Neo4j-Migrations-quarkus 1.4.0)

I think I'm using the driver wrong. Or is there a bug in the library? Please help!

Problem #1:
when I do subsequent queries, I get an empty Result for the second query, although I know there is at least 1 element.

import org.neo4j.driver.Result;
import org.neo4j.driver.Session;
import org.neo4j.driver.Value;
import org.neo4j.driver.Values;
import ac.simons.neo4j.migrations.core.JavaBasedMigration;
import ac.simons.neo4j.migrations.core.MigrationContext;

public class V001__JavaMigration implements JavaBasedMigration {

    @Override
    public void apply(MigrationContext context) {
        try (Session session = context.getSession()) {
            Result result = session.run(new Query("MATCH (n:HighestSnapshot) RETURN n"));

            while (result.hasNext()) {
                Value highestSnapshot = result.next().get(0);

                String groupId = highestSnapshot.get("groupId", "");
                String artifactId = highestSnapshot.get("artifactId", "");

                Result componentResults = session.run("MATCH (n {groupId: '$groupId', artifactId: '$artifactId'}) RETURN n",
                        Values.parameters("groupId", groupId, "artifactId", artifactId));
                
                componentResults.list(); // <---- empty list, but I know there is at least 1 element!

                // ...
            }
        }
    }
}

Problem #2:
I've read someones suggestion to use session.readTransaction() instead of session.run(), but when I do, a ResultConsumedException is thrown.

import org.neo4j.driver.Result;
import org.neo4j.driver.Session;
import org.neo4j.driver.Value;
import org.neo4j.driver.Values;
import ac.simons.neo4j.migrations.core.JavaBasedMigration;
import ac.simons.neo4j.migrations.core.MigrationContext;

public class V001__JavaMigration implements JavaBasedMigration {

    @Override
    public void apply(MigrationContext context) {
        try (Session session = context.getSession()) {
            Result result = session.readTransaction(tx -> tx.run(new Query("MATCH (n:HighestSnapshot) RETURN n")));

            while (result.hasNext()) {        // <----- ResultConsumedException
                // ...
            }
        }
    }
}

Results in:

Caused by: org.neo4j.driver.exceptions.ResultConsumedException: Cannot access records on this result any more as the result has already been consumed or the query runner where the result is created has already been closed.

1 ACCEPTED SOLUTION

For the no entry found:
You are putting the parameter into single quotes '$name'. This will not work because it will get treated as a string literal. Remove the quotes and the parameter replacement should work.

View solution in original post

3 REPLIES 3

You need to consume and process the results in the readTransaction. Something like the following. Note, you can also process the Result 'res' as a stream instead of using the iterator.

public void apply(MigrationContext context) {
try (Session session = context.getSession()) {
'list of your entity' result = session.readTransaction(tx -> {
Result res = tx.run(new Query("MATCH (n:HighestSnapshot) RETURN n"));
while (res.hasNext()) {
// map each Result Record to YourEntity and add to List to return
}
return 'list of your entity';
});
}
}

As a note, instead of your approach of using two chained queries, could you just merge the two into one cypher query that returns a list of your final results?

For the no entry found:
You are putting the parameter into single quotes '$name'. This will not work because it will get treated as a string literal. Remove the quotes and the parameter replacement should work.

Oh boy....

You are right!