首页 > 解决方案 > 在 Neo4j 中查询不存在的标签时,MyBatis 映射器永远不会返回

问题描述

我有这个非常简单的带有 MyBatis Spring Boot 启动器的 Spring Boot 2 应用程序:

@Slf4j
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Autowired
    UserMapper userMapper;

    @Bean
    public CommandLineRunner commandLineRunner() {
        return (args -> {
            final List<User> users = userMapper.getUsers();
            log.info("users: {}", users);
        });
    }

    @Bean
    @ConfigurationProperties(prefix="app.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

}

当我在 Neo4j 数据库中有一个用户时,它运行良好。但是,如果它们不存在,则对 getUsers 的调用将永远不会返回,不会超时,不会像应用程序永远卡住一样发生任何事情。任何想法为什么会发生这种情况?

编辑:显然它在 MyBatis 的 DefaultResultSetHandler 类中循环。

  private ResultSetWrapper getFirstResultSet(Statement stmt) throws SQLException {
    ResultSet rs = stmt.getResultSet();
    while (rs == null) {
      // move forward to get the first resultset in case the driver
      // doesn't return the resultset as the first result (HSQLDB 2.1)
      if (stmt.getMoreResults()) {
        rs = stmt.getResultSet();
      } else {
        if (stmt.getUpdateCount() == -1) {
          // no more results. Must be no resultset
          break;
        }
      }
    }
    return rs != null ? new ResultSetWrapper(rs, configuration) : null;
  }

ResultSet 为空,因为没有用户。但是 stmt.getMoreResults() 从 Neo4jInvocationHandler 中返回 true:

@Override public boolean getMoreResults() throws SQLException {
        this.checkClosed();
        return !(this.currentResultSet == null && this.currentUpdateCount == -1);
    }

currentUpdateCount 为 0,因为在 BoltNeo4jPreparedStatement 中:

@Override public boolean execute() throws SQLException {
        StatementResult result = executeInternal();

        boolean hasResultSet = hasResultSet(result);
        if (hasResultSet) {
            this.currentResultSet = BoltNeo4jResultSet.newInstance(this.hasDebug(), this, result, this.resultSetParams);
            this.currentUpdateCount = -1;
        } else {
            this.currentResultSet = null;
            try {
                SummaryCounters stats = result.consume().counters();
                this.currentUpdateCount = stats.nodesCreated() + stats.nodesDeleted() + stats.relationshipsCreated() + stats.relationshipsDeleted();
            } catch (Exception e) {
                throw new SQLException(e);
            }
        }
        return hasResultSet;
    }

我认为 getMoreResults 实现需要更新。
也许在 MyBatis PreparedStatementHandler 中他们应该检查 execute() 方法的返回值。

标签: neo4jmybatisspring-mybatis

解决方案


现在,neo4j-jdbc 3.3.1 已修复此问题。请参阅https://github.com/neo4j-contrib/neo4j-jdbc/issues/137


推荐阅读