/**
  * Close the resources.
  *
  * <p>The jdbc resultSet and statement need to be closed. Its important that this method is
  * called.
  */
 private void close() {
   try {
     if (dataReader != null) {
       dataReader.close();
       dataReader = null;
     }
   } catch (SQLException e) {
     logger.error(null, e);
   }
   try {
     if (pstmt != null) {
       pstmt.close();
       pstmt = null;
     }
   } catch (SQLException e) {
     logger.error(null, e);
   }
 }
  /** Execute the query returning the row count. */
  public BeanIdList findIds() throws SQLException {

    long startNano = System.nanoTime();

    try {
      // get the list that we are going to put the id's into.
      // This was already set so that it is available to be
      // read by other threads (it is a synchronised list)
      List<Object> idList = query.getIdList();
      if (idList == null) {
        // running in foreground thread (not FutureIds query)
        idList = Collections.synchronizedList(new ArrayList<Object>());
        query.setIdList(idList);
      }

      BeanIdList result = new BeanIdList(idList);

      SpiTransaction t = request.getTransaction();
      Connection conn = t.getInternalConnection();
      pstmt = conn.prepareStatement(sql);

      if (query.getBufferFetchSizeHint() > 0) {
        pstmt.setFetchSize(query.getBufferFetchSizeHint());
      }

      if (query.getTimeout() > 0) {
        pstmt.setQueryTimeout(query.getTimeout());
      }

      bindLog = predicates.bind(new DataBind(pstmt));

      ResultSet rset = pstmt.executeQuery();
      dataReader = new RsetDataReader(rset);

      boolean hitMaxRows = false;
      boolean hasMoreRows = false;
      rowCount = 0;

      DbReadContext ctx = new DbContext();

      while (rset.next()) {
        Object idValue = desc.getIdBinder().read(ctx);
        idList.add(idValue);
        // reset back to 0
        dataReader.resetColumnPosition();
        rowCount++;

        if (maxRows > 0 && rowCount == maxRows) {
          hitMaxRows = true;
          hasMoreRows = rset.next();
          break;
        }
      }

      if (hitMaxRows) {
        result.setHasMore(hasMoreRows);
      }

      long exeNano = System.nanoTime() - startNano;
      executionTimeMicros = (int) exeNano / 1000;

      return result;

    } finally {
      close();
    }
  }