【问题标题】:On Google App Engine (GAE), how do I search on the Key/ID field?在 Google App Engine (GAE) 上,如何搜索 Key/ID 字段?
【发布时间】:2010-09-21 20:40:00
【问题描述】:

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

【问题讨论】:

    标签: google-app-engine jdo


    【解决方案1】:

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

    顺便说一句,尝试构造一个查询以通过它的键获取某些东西是您不需要做的事情。尽管这是您使用 SQL 数据库的方式,但 Google Data Store 的处理方式有所不同,这是其中一种情况,Google App Engine 可以让您直接获得您想要的东西,而不是通过构建查询的麻烦。毕竟,您应该在数据库中只有一个具有特定键的实体,因此在这种情况下,您不需要 GQL 查询的其余机制,因此可以将其全部跳过以提高效率。

    【讨论】:

    【解决方案2】:

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

    【讨论】:

    • JDO 标准也是广为人知的标准,您可以将相同的 JDO 代码与其他 JDO 实现一起使用(如果您忽略 Google 的细节),正如 Google campfire 的原始视频中所清楚展示的那样2009 年 4 月。
    • 是的,但是 JPA 在 IMO 的采用方面取得了更大的成功。
    • 重点是用户问了一个问题,他正在使用JDO。他没有问你会推荐什么 API,只是问我该如何做这件事(使用 JDO,他现在拥有什么)。 “啊,你可以用 JPA 来做,但是你必须改变你所有的持久性代码”......不是真的那样回答他;-)
    猜你喜欢
    • 1970-01-01
    • 2012-08-26
    • 2011-03-11
    • 2014-07-14
    • 1970-01-01
    • 2012-09-11
    • 2013-03-31
    • 1970-01-01
    • 2011-07-15
    相关资源
    最近更新 更多