代码之家  ›  专栏  ›  技术社区  ›  grandouassou

在Neo4j中查询不存在的标签时,MyBatis mapper从不返回

  •  0
  • grandouassou  · 技术社区  · 8 年前

    我有一个非常简单的Spring Boot 2应用程序和MyBatis Spring Boot starter:

    @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;
      }
    

    结果集为null,因为没有用户。 但是stmt。getMoreResults()从Neo4jinIvocationHandler中返回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()方法的返回值。

    1 回复  |  直到 8 年前
        1
  •  0
  •   grandouassou    7 年前

    此问题现已通过neo4j jdbc 3.3.1修复。看见 https://github.com/neo4j-contrib/neo4j-jdbc/issues/137