husayt
husayt

Reputation: 15149

Appengine Key serializes transient appIdNamespace

I am creating a com.google.appengine.api.datastore.Key in namespace A and adding it as a field to DeferredTask to run in different namespace B. That task is then sent to a Queue and is being executed on a different box.

Because, it is created in namespace A that key has A as its original namespace value (in its appIdNamespace field).

But as the key's appIdNamespace field is transient and DeferredTask uses serialization I expect the appIdNamespace field to be null on deserialization (and thus to get initialised to have namespace value of B) when being run from namespace B.

But instead key still has A as a value for namespace in its appIdNamespace field after deserialization, when task runs in namespace B.

I am sure I am missing something here, but can't explain. What am I missing here?

Upvotes: 1

Views: 125

Answers (1)

icza
icza

Reputation: 418067

Yes, I just checked. Serialization process is overridden for Key which serializes the appIdNamespace if it's not null via the appId field which is not transient:

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

And readObject() properly decodes the appIdNamespace from the deserialized appId field:

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);
}

Source: Key.java

Upvotes: 1

Related Questions