Neo4j Java 驱动程序 - 无法访问此结果的记录

Neo4j Java Driver - Cannot access records on this result

我正在使用 neo4j java 驱动程序并尝试执行 Cyphers.I 得到一个 exception.I 我在网上搜索了很长时间。但是没有用。请帮助或尝试提供一些想法如何实现这一目标。

1.This是我添加的驱动:

        <dependency>
            <groupId>org.neo4j.driver</groupId>
            <artifactId>neo4j-java-driver-spring-boot-starter</artifactId>
            <version>4.1.1.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.neo4j/neo4j-ogm-core -->
        <dependency>
            <groupId>org.neo4j</groupId>
            <artifactId>neo4j-ogm-core</artifactId>
            <version>3.2.20</version>
        </dependency>

2.The函数:

     public Result readCyphers(String cypher) {

        Result result = null;

        Driver driver = null;
        Session session = null;

        try {
            //driver
            driver = GraphDatabase.driver(uri, AuthTokens.basic(username, password));
            //session
            session = driver.session();

            //run
            result = session.run(cypher);

        } catch (Exception e) {
            throw e;
        } finally {
            session.close();
            driver.close();
        }

        return result;
    }

3.call函数

  @Test
    void readCyphersTest() {

        String cypher = "MATCH(N:WechatDepartment) \n" +
                "WHERE N.departmentId = 117 \n" +
                "RETURN ID(N) as id, N.departmentId as departmentId, N.name as name, N.order as order, N.enable as enable";
        Result result = readCyphers(cypher);

        //There is an exception here
        System.out.println("result.list().size():" + result.list().size());
    }

4.exception:

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.

提前致谢

(如果只打算使用驱动,则不需要Neo4j OGM)

会话关闭后,您将无法访问驱动程序的 Result 实例。 您应该在会话打开时遍历记录并 return 您想要的结果,例如:

    public <T> List<T> readCyphers(String cypher, Function<Record, T> mapper) {
        try (Driver driver = GraphDatabase.driver(uri, AuthTokens.basic(username, password));
             Session session = driver.session()) {

            Result result = session.run(cypher);
            return result.list(mapper);
        }
    }

但是请注意,您不应该在每次要 运行 查询时都创建一个 Driver 实例,因此应该在之前创建驱动程序,例如:

class CypherExecutor implements AutoCloseable {

    private final Driver driver;

    public CypherExecutor(String uri, String username, String password) {
        this.driver = GraphDatabase.driver(uri, AuthTokens.basic(username, password))
    }

    public <T> List<T> readCyphers(String cypher, Function<Record, T> mapper) {
        try (Session session = driver.session()) {
            Result result = session.run(cypher);
            return result.list(mapper);
        }
    }

    @Override
    public void close() throws Exception {
        driver.close();
    }
}

CypherExecutor 最好仅在应用程序停止时关闭(通过 try-with-resources 块)。

此外,transaction functions 更健壮(面对集群机器故障、领导者重新选举等),应该改用,所以 readCyphers 应该是(假设只读查询):

    public <T> List<T> readCyphers(String cypher, Function<Record, T> mapper) {
        try (Session session = driver.session()) {
            return session.readTransaction(tx -> tx.run(cypher).list(mapper));
        }
    }

最后一点,这种抽象并没有给 table 带来太多好处,因此您可以直接在代码库中使用驱动程序 API 而不是使用这种间接方式。

完整代码,包含导入:

import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.Driver;
import org.neo4j.driver.GraphDatabase;
import org.neo4j.driver.Record;
import org.neo4j.driver.Session;

import java.util.List;
import java.util.function.Function;

class CypherExecutor implements AutoCloseable {

    private final Driver driver;

    public CypherExecutor(String username, String password, String uri) {
        this.driver = GraphDatabase.driver(uri, AuthTokens.basic(username, password))
    }

    public <T> List<T> readCyphers(String cypher, Function<Record, T> mapper) {
        try (Session session = driver.session()) {
            return session.readTransaction(tx -> tx.run(cypher).list(mapper));
        }
    }

    @Override
    public void close() throws Exception {
        driver.close();
    }
}