In my model I have
@Entity
public class Ent implements Serializable {
@Id
private long key;
@Parent
private Key<Ent> parentKey;
}
entity which creates a simple hierarchy (actually just 2-levels in my case). I would like to filter for just the roots of the hierarchy, which is defined by having no parent (parentKey = null
).
I tried using filter()
in Objectify, but got an exception
java.lang.IllegalArgumentException: @Parent fields cannot be filtered on. Perhaps you wish to use filterKey() or ancestor() instead?
Then I tried using ancestor()
, but it seems to not support null
values:
javax.servlet.ServletException: java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "pojo" is null
at com.google.apphosting.runtime.jetty9.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:117)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.handler.SizeLimitHandler.handle(SizeLimitHandler.java:96)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:516)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
at com.google.apphosting.runtime.jetty9.RpcConnection.handle(RpcConnection.java:269)
at com.google.apphosting.runtime.jetty9.RpcConnector.serviceRequest(RpcConnector.java:100)
at com.google.apphosting.runtime.jetty9.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:184)
at com.google.apphosting.runtime.RequestRunner.dispatchServletRequest(RequestRunner.java:262)
at com.google.apphosting.runtime.RequestRunner.dispatchRequest(RequestRunner.java:227)
at com.google.apphosting.runtime.RequestRunner.run(RequestRunner.java:193)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:273)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "pojo" is null
at com.googlecode.objectify.impl.Keys.getMetadataSafe(Keys.java:70)
at com.googlecode.objectify.impl.Keys.rawKeyOf(Keys.java:52)
at com.googlecode.objectify.impl.Keys.anythingToRawKey(Keys.java:122)
at com.googlecode.objectify.impl.QueryImpl.setAncestor(QueryImpl.java:221)
at com.googlecode.objectify.impl.SimpleQueryImpl.ancestor(SimpleQueryImpl.java:69)
at
I suppose I should use filterKey()
, the question is how do I create a "filtering key" that will accept any id
, but only null
parent...
It's probably not possible, my data actually doesn't encode parentKey
inside the entity's key
, which is necessary for @Parent
feature, removing that annotation solved the issue.
I hate to give you bad news, but I don't think you can. There's no index for "entities which don't have an ancestor". It's just not a datastore operation.
I would add an indexed field to your entities to enable the query you want. You may have to map/reduce across all of your entities, resaving them to add the field.