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.

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.... :anguished:

You are right! :man_facepalming: