在Google App Engine(GAE)上,如何搜索Key / ID字段?

时间:2010-09-21 20:40:01

标签: google-app-engine jdo

我有这个代码(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

生成此错误:

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]

但我不确定它想要什么。我正在尝试搜索JDO id字段,我认为我读过该字段的特殊名称__key__in the documentation

我已经尝试了两个

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

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

具有相同的结果。那么,我做错了什么?或者,更重要的是,我该如何正确地做到这一点?

谢谢!

编辑:为了完整起见,这是最终的工作代码(基于Gordon的答案,我已经接受了正确的答案):

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;

2 个答案:

答案 0 :(得分:3)

如果您的目标是按键获取对象,那么您应该使用PersistenceManager的getObjectByID()方法。更多详情here

顺便说一下,尝试构建一个查询来获取它的关键是你不应该做的事情。虽然这是您使用SQL数据库的方式,但谷歌数据存储的工作方式不同,这是其中一种情况,而不是经历构建查询的麻烦,谷歌应用程序引擎让您直接得到你想要的东西。毕竟,您应该只在数据库中有一个具有特定键的实体,因此在这种情况下,您需要的GQL查询的其余部分中没有任何内容,因此可以跳过它们以提高效率。

答案 1 :(得分:-1)

我建议您使用JPA(http://code.google.com/appengine/docs/java/datastore/usingjpa.html)来访问GAE中的数据,它具有非常重要的优势,您可以使用广为人知和记录的JPA标准(及其JPAQL查询语言)来以便携方式执行此类操作(如果您坚持使用JPA标准,您的代码将适用于GAE,Hibernate或EclipseLink而无需修改)