On Google App Engine (GAE), how do I search on the Key/ID field?

淺唱寂寞╮ 提交于 2020-01-02 11:04:23

问题


I've got this code (Java, GAE):

// Much earlier:
playerKey = KeyFactory.keyToString(somePlayer.key);

// Then, later...
PersistenceManager pm = assassin.PMF.get().getPersistenceManager();

Key targetKey = KeyFactory.stringToKey(playerKey);
Query query = pm.newQuery(Player.class);
query.setFilter("__key__ == keyParam");
query.declareParameters("com.google.appengine.api.datastore.Key keyParam");
List<Player> players = (List<Player>) query.execute(targetKey); // <-- line 200

which generates this error:

javax.jdo.JDOFatalUserException: Unexpected expression type while parsing query.  Are you certain that a field named __key__ exists on your object?
    at org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:354)
    at org.datanucleus.jdo.JDOQuery.execute(JDOQuery.java:252)
    at myapp.Player.validPlayerWithKey(Player.java:200)
    // [etc., snip]

But I'm not sure what it wants. I'm trying to search on the JDO id field, which I I thought I read had the special name __key__, in the documentation.

I've tried it with both

query.setFilter("__key__ == keyParam");

and

query.setFilter("ID == keyParam");

with the same results. So, what am I doing wrong? Or, more importantly, how do I do it correctly?

Thanks!

Edit: For completeness's sake, here is the final, working code (based on Gordon's answer, which I have accepted as correct):

Player result = null;
if (playerKey == null)
{
    log.log(Level.WARNING, "Tried to find player with null key.");
}
else
{
    PersistenceManager pm = assassin.PMF.get().getPersistenceManager();

    try {
        result = (Player) pm.getObjectById(Player.class, playerKey);
    } catch (javax.jdo.JDOObjectNotFoundException notFound) {
        // Player not found; we will return null.
        result = null;
    }

    pm.close();
}

return result;

回答1:


If your objective is to get an object by key, then you should use the PersistenceManager's getObjectByID() method. More details here.

As an aside, trying to construct a query to get something by it's key is something you shouldn't need to do. Although this is how you would work with an SQL database, the Google Data Store does things differently, and this is one of those cases where rather than go through the trouble of constructing a query, Google App Engine lets you get what you want directly. After all, you should only have one entity in the database with a particular key, so there's nothing in the rest of the machinery of a GQL query that you need in this case, hence it can all be skipped for efficiency.




回答2:


I would recommend you to use the JPA ( http://code.google.com/appengine/docs/java/datastore/usingjpa.html ) to access your data in GAE, it has the very important advantage that you can use the widely known and documented JPA standard (and its JPAQL querying language) to do this kind of things, in portable way (if you stick to the JPA standard, your code will work for GAE, for Hibernate or with EclipseLink without modification)



来源:https://stackoverflow.com/questions/3764300/on-google-app-engine-gae-how-do-i-search-on-the-key-id-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!