Upgrading Objectify v5 to v6
Objectify v6 attempts to preserve as much of the public API surface of v5 as possible, but uses a whole new Google-provided SDK to access the datastore. In cases where Objectify's API exposes SDK classes, or the new SDK has differing behavior, changes in your application may be required. These are catalogued below.
You will need to call
ObjectifyService.init(), possibly passing in a custom
ObjectifyFactoryinstance. The previous behavior of starting out with a default
ObjectifyFactoryincurs a connection cost and may fail in environments which require a custom
ObjectifyFactoryuses the default environment credentials (ie,
DatastoreOptions.getDefaultInstance().getService(). If you need to construct a special
Datastore, you can pass this in to the
There's no longer an automatically provisioned memcache service. Objectify's memcache integration relies on the Spymemcached library to talk to a plain old memcached server running on a port/IP address. The default ObjectifyFactory constructor disables memcache (for now); pass in an explicit
MemcachedClientto enable caching.
The Cloud SDK generates a new format for stringified keys (
key.toUrlSafe()), which is something to be aware of if you store these keys in other databases (or user-bookmarked urls). To help, Objectify accepts either form when constructing keys with
Key.create(String). To generate one form or the other, call one of:
key.toUrlSafe(), which looks like
key.toLegacyUrlSafe(), which looks like
The memcached serialization format for Objectify v5 and v6 differ. You can run v5 and v6 in parallel against the same datastore, but not the same memcached. Not that you could anyways; there is not currently a Cloud SDK interface to the memcached service!
Java serialization of Objectify's
Ref<?>classes is not compatible between v5 and v6. If you
@Serializestructures that contain fields of these types, you will have problems. Objectify's
Key<?>is just a wrapper for the SDK's
Key, and that is now a totally different class.
ObjectifyFactory.allocateIdRange()has been removed. There is no longer an explicit range-allocation function in the SDK. You can still allocate ids (and blocks of ids) using
ofy().consistency(Consistency.EVENTUAL).load()...uses an SDK enum that no longer exists. The new code is
ofy().deadline(blah)has been removed. The new SDK does not offer this ability; if you want to change connection behavior, use the SDK
DatastoreOptionsto construct a special
Datastoreand pass it to the
NOT and IN filters are not supported by the new SDK. You will get a runtime error if you try to
ofy().load().type(Thing.class).filter("field !=", value)or
filter("field IN" values).
The new SDK uses a new set of classes to manage query cursors, and Objectify has always exposed these directly. If you use cursors, you will have to change your code:
com.googlecode.objectify.cmd.QueryResultIterable(an Objectify-provided interface since there is no analogue in the SDK)
If you use composite filters, the new SDK has a new set of
There is no more
Query.reverse()method, as this is no longer supported by the underlying SDK.
The underlying SDK does not have a query
count()operation. Objectify simulates this by issuing a keys-only query and counting the keys. This might perform differently from the old SDK; then again, the old SDK was probably just doing this behind the scenes (only Google knows for sure).
The old SDK did not save empty lists (it just ignored them). The new SDK does save empty lists. This doesn't matter a whole lot when working with POJOs but if you are using Objectify and the low-level APIs simultaneously you may notice the difference.
The new SDK has a quirk when saving list properties. If some values are indexed and others aren't, the indexed ones get reordered to the front of the list. To work around this behavior, whenever Objectify detects a heterogenously-indexed list, it forces everything in the list to be indexed.
Blobs can be indexed in the new SDK. In the old SDK, instructions to index a
Blobwere simply ignored; in the new SDK, the instruction is respected - but you'll get an error if you exceed 1500 bytes. Note that this applies to
@Serializefields as well.
Nearly every internal API in Objectify has changed in some way, including the
TranslatorAPIs. If it isn't obvious what you need to do, ask on the Objectify google group.