title: Why is the cursor returned from my GAE datastore query null?
body: <p>I am trying to use GAE cursors using this page <a href="https://cloud.google.com/appengine/docs/standard/java/datastore/query-cursors" rel="nofollow noreferrer">https://cloud.google.com/appengine/docs/standard/java/datastore/query-cursors</a> as inspiration. 
  The problem is that the cursor returned by my code below is null - I do not understand why, as I think I use the same structure as the above link, i.e. the result from the query is a QueryResultList, and I use the getCursor method on the result to obtain a reference to the cursor.
  The NON_SENT_MATCHES_LIMIT is 20 and if I set no limit on the query there are more than 2000 entities, so I would expect a non-null cursor as a result.</p>
  
  <p>Can anybody explain to me why the cursor is null?</p>
  
  <pre><code>public ProductRuleMatchWithCursor getNonSentMatchesBatch(Transaction transaction, long shopId, Cursor startCursor) {
      Query.FilterPredicate activeOrderProduct = new Query.FilterPredicate(ProductRuleMatchDBFields.ACTIVE, Query.FilterOperator.EQUAL, true);
      Query.FilterPredicate pendingOrderProduct = new Query.FilterPredicate(ProductRuleMatchDBFields.MATCH_STATUS, Query.FilterOperator.EQUAL, MatchStatus.PENDING.getId());
      Query.FilterPredicate failedOrderProduct = new Query.FilterPredicate(ProductRuleMatchDBFields.MATCH_STATUS, Query.FilterOperator.EQUAL, MatchStatus.FAILED_CAN_RECOVER.getId());
      Query query = new Query(ProductRuleMatchDBFields.PRODUCT_RULE_MATCH_TABLE_NAME).setFilter(Query.CompositeFilterOperator.and(activeOrderProduct, Query.CompositeFilterOperator.or(pendingOrderProduct, failedOrderProduct)));
      query.setAncestor(KeyFactory.createKey(ShopDBFields.SHOP_TABLE_NAME, shopId));
      FetchOptions fetchOptions = FetchOptions.Builder.withLimit(NON_SENT_MATCHES_LIMIT);
      if (startCursor != null){
          fetchOptions.startCursor(startCursor);
      }
      QueryResultList&lt;Entity&gt; entities = datastore.prepare(transaction, query).asQueryResultList(fetchOptions);
  
      List&lt;ProductRuleMatch&gt; matches = new ArrayList&lt;&gt;();
      for (Entity entity : entities) {
          matches.add(createModelFromEntity(entity));
      }
      Cursor cursor = entities.getCursor();
      logger.info("The cursor is: " + cursor);
      return new ProductRuleMatchWithCursor(matches, cursor);
  }
  </code></pre>