DevelopeXCode
DevelopeXCode

Reputation: 65

GAE and Objectify query and error using order()

I am just working on a Demo project and one of the methods provides a basic query on a Type.

    public List<Conference> filterPlayground(){

      Query<Conference> query = (ofy().load().type(Conference.class)).order("name");

      query = query.filter("topics =", "Medical Innovations");  
      query = query.filter("city =","London");

      return query.list();
}

My Conference Entity has @Index for name, city and topics.

But when I run the method in API Explorer I get an Exception... (see below). Any quick pointers as to why using the order method causes this. I know it is the order method as without it there is no error.

Uncaught exception from servlet
java.io.IOException:    com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingExcepti on: no matching index found. recommended index is:
- kind: Conference
 properties:
 - name: city
 - name: topics
 - name: name

The suggested index for this query is:
<datastore-index kind="Conference" ancestor="false" source="manual">
<property name="city" direction="asc"/>
<property name="topics" direction="asc"/>
<property name="name" direction="asc"/>
</datastore-index>

(through reference chain: java.util.HashMap["items"])
at com.google.api.server.spi.response.ServletResponseResultWriter.writeValueAs    String(ServletResponseResultWriter.java:187)
at com.google.api.server.spi.response.ServletResponseResultWriter.write(ServletResponseResultWriter.java:74)
at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:394)
at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:113)
at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:71)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:37)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:48)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at     com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:257)
at     org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:145)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:511)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:446)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:453)
at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:276)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:312)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:304)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:450)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:235)
at java.lang.Thread.run(Thread.java:745)
Caused by:     com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: no matching index found. recommended index is:
- kind: Conference
  properties:
  - name: city
  - name: topics
  - name: name

The suggested index for this query is:
<datastore-index kind="Conference" ancestor="false" source="manual">
<property name="city" direction="asc"/>
<property name="topics" direction="asc"/>
<property name="name" direction="asc"/>
</datastore-index>

(through reference chain: java.util.HashMap["items"])
at com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:218)
at com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:183)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.SerializerBase.wrapAndThrow(SerializerBase.java:140)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.MapSerializer.serializeFields(MapSerializer.java:266)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.MapSerializer.serialize(MapSerializer.java:186)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.MapSerializer.serialize(MapSerializer.java:23)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ObjectWriter._configAndWriteValue(ObjectWriter.java:456)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ObjectWriter.writeValueAsString(ObjectWriter.java:393)
at com.google.api.server.spi.response.ServletResponseResultWriter.writeValueAsString(ServletResponseResultWriter.java:183)
... 38 more

Caused by: com.google.appengine.api.datastore.DatastoreNeedIndexException: no matching index found. recommended index is: - kind: Conference properties: - name: city - name: topics - name: name

The suggested index for this query is:

at com.google.appengine.api.datastore.DatastoreApiHelper.translateError(DatastoreApiHelper.java:59)
at com.google.appengine.api.datastore.DatastoreApiHelper$1.convertException(DatastoreApiHelper.java:128)
at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:97)
at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:89)
at com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:76)
at com.google.appengine.api.datastore.FutureHelper.quietGet(FutureHelper.java:36)
at com.google.appengine.api.datastore.BaseQueryResultsSource.getIndexList(BaseQueryResultsSource.java:159)
at com.google.appengine.api.datastore.BaseQueryResultsSource.loadMoreEntities(BaseQueryResultsSource.java:192)
at com.google.appengine.api.datastore.BaseQueryResultsSource.loadMoreEntities(BaseQueryResultsSource.java:171)
at com.google.appengine.api.datastore.QueryResultIteratorImpl.ensureLoaded(QueryResultIteratorImpl.java:148)
at com.google.appengine.api.datastore.QueryResultIteratorImpl.hasNext(QueryResultIteratorImpl.java:64)
at com.googlecode.objectify.impl.KeysOnlyIterator.hasNext(KeysOnlyIterator.java:29)
at com.googlecode.objectify.impl.ChunkIterator.next(ChunkIterator.java:48)
at com.googlecode.objectify.impl.ChunkIterator.next(ChunkIterator.java:20)
at com.google.common.collect.Iterators$5.hasNext(Iterators.java:597)
at com.google.common.collect.Iterators$PeekingImpl.hasNext(Iterators.java:1216)
at com.googlecode.objectify.impl.ChunkingIterator.hasNext(ChunkingIterator.java:51)
at com.google.common.collect.Lists.newArrayList(Lists.java:144)
at com.google.common.collect.Lists.newArrayList(Lists.java:125)
at com.googlecode.objectify.util.MakeListResult.translate(MakeListResult.java:21)
at com.googlecode.objectify.util.MakeListResult.translate(MakeListResult.java:11)
at com.googlecode.objectify.util.ResultTranslator.nowUncached(ResultTranslator.java:21)
at com.googlecode.objectify.util.ResultCache.now(ResultCache.java:30)
at com.googlecode.objectify.util.ResultProxy.invoke(ResultProxy.java:34)
at com.sun.proxy.$Proxy30.iterator(Unknown Source)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:45)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:86)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.MapSerializer.serializeFields(MapSerializer.java:262)
... 45 more

Upvotes: 1

Views: 202

Answers (2)

Dan Cornilescu
Dan Cornilescu

Reputation: 39824

Your app needs a different index definition for ordered queries. A direction is needed as well. See How to fix index error when querying GAE datastore?

Typically the devserver is able to automatically generate/update the indexes in your local development environment according to the queries your local app actually performs. But you need to manually upload the updated index file to GAE (and make sure indexing is completed) before your GAE app can actually use it.

If the devserver fails to automatically generate/update the index file you can still do it manually.

Upvotes: 1

konqi
konqi

Reputation: 5227

The error basically tells you everything you need to know. You should add:

<datastore-index kind="Conference" ancestor="false" source="manual">
<property name="city" direction="asc"/>
<property name="topics" direction="asc"/>
<property name="name" direction="asc"/>
</datastore-index>

to your index configuration.

It doesn't matter that you have individual indexes on these properties. You need to create a composite index (as described in the error message) for this query.

Upvotes: 1

Related Questions