【问题标题】:Appengine Key serializes transient appIdNamespaceAppengine Key 序列化瞬态 appIdNamespace
【发布时间】:2014-08-06 08:32:17
【问题描述】:

我正在命名空间A 中创建一个com.google.appengine.api.datastore.Key,并将其作为字段添加到DeferredTask 以在不同的命名空间B 中运行。然后将该任务发送到队列并在不同的盒子上执行。

因为它是在命名空间 A 中创建的,该键以 A 作为其原始命名空间值(在其 appIdNamespace 字段中)。

但是由于密钥的 appIdNamespace 字段是瞬态的并且 DeferredTask 使用序列化,我希望 appIdNamespace 字段在反序列化时为空(因此被初始化为具有 B 的命名空间值)运行时命名空间B

但是,当任务在命名空间B 中运行时,反序列化后,key 在其appIdNamespace 字段中仍然具有A 作为命名空间的值。

我确定我在这里遗漏了一些东西,但无法解释。我在这里错过了什么?

【问题讨论】:

  • Key 的序列化过程可能会被覆盖,它也会对appIdNamespace 进行序列化。

标签: java google-app-engine objectify google-cloud-datastore


【解决方案1】:

是的,我刚刚检查过。序列化过程覆盖为Key,如果它不是null,则通过appId 字段而不是transient 序列化appIdNamespace

private void writeObject(ObjectOutputStream out) throws IOException {
    if (appIdNamespace != null) {
      appId = appIdNamespace.toEncodedString();
    }
    out.defaultWriteObject();
}

并且readObject() 正确解码来自反序列化的appId 字段的appIdNamespace

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject();
    if (appId != null) {
        appIdNamespace = AppIdNamespace.parseEncodedAppIdNamespace(appId);
        appId = null;
    } else {
        appIdNamespace = new AppIdNamespace(DatastoreApiHelper.getCurrentAppId(), "");
    }
    validateAppIdNamespace(parentKey, appIdNamespace);
}

来源:Key.java

【讨论】:

  • 谢谢,这解释了这个谜。现在是有道理的。尽管注释在文档中很有用,但要对此提出警告。
猜你喜欢
  • 2010-12-27
  • 2015-10-18
  • 2017-03-05
  • 1970-01-01
  • 2021-04-22
  • 2018-09-23
  • 2012-03-30
  • 2016-07-01
  • 1970-01-01
相关资源
最近更新 更多