Objectify: a typed data access API for Google Cloud Datastore
The simplest convenient interface to the Google Cloud Datastore
At a glance
- What is it?
- Objectify is an MIT licensed Java data access API built specifically for Google Cloud Datastore, sitting between the low-level client libraries and the JPA and JDO specifications, with typed entities, a fluent query interface, transactions, memcache caching and schema migration helpers. The judgement is that its most useful property is transparency, you can see the native features rather than guessing at them, and that the version six boundary is the decision a reader has to make first.
- Who is it for?
- Objectify fits a Java team that has committed to Google Cloud Datastore and wants an object model without the impedance mismatch of JPA, because the entities are ordinary classes with an annotation, the queries read as a chain of calls, and nothing in the native feature set is hidden from you.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 103 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A middle ground between the raw client and JPA
Objectify is a Java data access API designed specifically for Google Cloud Datastore, which the readme names in its three guises as the Cloud Datastore, the Google App Engine Datastore, and Firestore in Cloud Datastore mode.
The positioning is stated directly. Objectify occupies a middle ground, easier to use and more transparent than JDO or JPA, but significantly more convenient than the low-level API libraries that Google provides. The stated goal is to make novices immediately productive while also exposing the full power of the Datastore.
Those two goals pull in opposite directions in a persistence layer, and most frameworks resolve the tension by hiding one side. JPA hides the datastore behind a specification, which is portable and predictable and cannot express the things a datastore does well. The raw client libraries hide nothing and express everything, and require you to assemble a query, a key and a result by hand for every call.
Objectify takes the middle position, and the feature list is really an argument about what that means. It surfaces all the native datastore features, including batch operations, queries, transactions, asynchronous operations and partial indexes. It provides type-safe key and query classes using Java generics. It provides a human-friendly query interface. And it lets you persist, retrieve, delete and query your own typed objects.
The project is MIT licensed, its primary language is Java, and the last push to the repository was on 2026-07-12.
The version boundary decides where your code can run
There is an important note about versions near the top of the readme, and it is the first thing to check when you are choosing a version.
Objectify version 5 and prior use the Google App Engine API for Java, and therefore can only be used within Google App Engine Standard. Objectify version 6 and later use the Cloud Datastore API and can be used from anywhere: App Engine Standard, App Engine Flex, Compute Engine, or outside Google Cloud entirely.
That is a larger difference than a version number usually carries. In version 5 the library is coupled to the runtime of one specific platform, and a test that uses it needs that platform's environment. In version 6 the transport is the ordinary Cloud Datastore API, so the same code runs on a developer laptop, in a container, and in a managed instance, and the only thing that changes between them is where the credentials come from.
The readme points at the frequently asked questions page in the wiki for more on the change, which is the right place to look because the migration touches the dependency, the API surface and the deployment model at once.
For a reader evaluating the library today, the practical summary is that the current line is the portable one, and that choosing an old version is a choice to be tied to App Engine Standard. The repository has no GitHub releases, so the version history lives in the wiki and in the changelog rather than in tags.
The entity is a plain class with an annotation
The object model is deliberately plain. A class is annotated and its fields are used as the properties, and the readme shows the whole cycle in a few lines:
@Entity
class Car {
@Id String vin; // Can be Long, long, or String
String color;
}
ofy().save().entity(new Car("123123", "red")).now();
Car c = ofy().load().type(Car.class).id("123123").now();
ofy().delete().entity(c);Three things are notable in that snippet. The identifier is chosen by the application, and the comment says the id can be a Long, a long or a String, which matters because a datastore key has a kind and a name and the choice of name type is a schema decision.
The second is the shape of the calls. Every operation starts from ofy(), and each step narrows what is going to happen, save then entity then now. The trailing now is what makes the call synchronous, and it is the only part of the chain that a reader has to learn.
The third is that there is no session, no EntityManager and no persistence context. The result of a load is the object you asked for, and the object you loaded is the object you pass to delete. That absence is the practical difference from JPA, and it is why a JPA user finds Objectify obvious and a JPA user also finds it strange.
The class itself is unremarkable, which is the point. There is no base class, no proxy and no no-argument constructor requirement to satisfy, so a domain class that already exists in your application can be annotated rather than rewritten.
Everything the datastore does is still reachable
The feature list is long, and the entries that matter are the ones about what is not hidden.
Objectify surfaces all native datastore features, including batch operations, queries, transactions, asynchronous operations and partial indexes. Partial indexes in particular are a datastore concept rather than a general persistence concept, and a library that claims to expose the full power has to give you a way to declare them.
On the type safety side, it provides type-safe key and query classes using Java generics, so a key is typed by the entity class it refers to and a query carries its result type through the call chain rather than through a cast at the end. And it provides a human-friendly query interface, which is the other half of the same idea, since a query that reads as a sequence of filters is a query a reviewer can check.
The other entries are about the practical problems of running this in production. It can automatically cache your data in memcache for improved read performance, it provides a simple and easy to understand transaction model, and it provides built-in facilities to help migrate schema changes forward.
That last one deserves attention. In a datastore the schema lives in the class, and changing a class is a change to the shape of the data that is already stored, which means a deployment can break reads that worked yesterday. A library that helps with schema migration is acknowledging a problem that most Java persistence layers push onto the application developer.
The readme also makes a point about testing, that Objectify has an extensive test suite to prevent regressions, which for a library of this kind is a reasonable place to spend the effort.
Caching, polymorphism and a wiki for the concepts
Three of the capabilities deserve a closer look, because they are the ones that decide whether the library fits your data.
The memcache integration is automatic. Objectify can cache your data in memcache for improved read performance, which is the datastore's answer to a read-heavy workload, and doing it inside the data access layer rather than in application code means the cache key and the invalidation are consistent with the datastore's own view of the entity.
The polymorphism support is the second. Objectify can store polymorphic entities and perform true polymorphic queries, and the word true is doing work. Storing a hierarchy is straightforward, and querying across a hierarchy without knowing the concrete type is the part that is hard, because the datastore's kind is the unit of the index, so a query over a base class has to be expressed over the kinds that extend it.
The transaction model is the third, and it is described as simple and easy to understand, which in this context means it does not attempt to be a general transaction abstraction. Datastore transactions are limited in scope, they are single group transactions, and a model that pretends otherwise would be harder to use than one that shows the limits.
The documentation is in the Objectify Wiki, and the readme describes it as thorough, covering concepts as well as use cases. That distinction is the useful one for a library like this, because the concepts are what a datastore newcomer needs, since the terms of the underlying system, kinds, keys, entities, indexes, transactions, are the vocabulary the library is built on.
Maven Central, a user group and no tagged releases
The distribution story is conventional and the support story is the part to notice.
Objectify is released to the Maven Central repository and can be downloaded directly from there, with the wiki holding the details of the coordinates. The documentation is in the Objectify Wiki, and help is provided through the Objectify App Engine User Group, a Google Group where the questions of the community are answered.
The repository itself is small and tells you the shape of the project. There is a src directory, a pom.xml at the root, a .travis.yml for continuous integration, a license file and a logging.properties file, which is the kind of detail that says the library has a logging configuration that users are expected to tune.
The project is MIT licensed and has no GitHub releases, so the version history is in the wiki and in the source rather than in tags, and the last push was on 2026-07-12, which is a few months before the date this article is written about.
For an adopter, the practical point is that this is a library with a long history and a stable API surface, where the interesting changes have been in what it supports, the move from the App Engine API to the Cloud Datastore API, rather than in churn. The readme is explicit that the goal is to expose the full power of the datastore while keeping the interface simple, and if you have used the low-level client libraries before, the library's whole appeal is that you keep the control and lose the ceremony.
Editorial conclusion
Objectify fits a Java team that has committed to Google Cloud Datastore and wants an object model without the impedance mismatch of JPA, because the entities are ordinary classes with an annotation, the queries read as a chain of calls, and nothing in the native feature set is hidden from you. It is the wrong choice if you want a portable persistence layer, because the API is specific to one datastore, and it is the wrong choice if you are still on the App Engine API for Java, because version five and earlier only run inside App Engine Standard while version six and later are the ones that run anywhere. Before you adopt it, check the version line your project depends on, decide whether the memcache caching is a feature you want enabled by default, and read the wiki rather than the readme, because the documentation there is where the concepts are explained.
Frequently asked questions
What is Objectify?
It is an MIT licensed Java data access API designed specifically for Google Cloud Datastore, positioned between the low-level Google client libraries and JPA or JDO. It provides typed entities, type-safe keys and queries, transactions, batch operations, partial indexes and memcache caching.
What is the difference between Objectify 5 and Objectify 6?
Version 5 and earlier use the Google App Engine API for Java and can only be used inside App Engine Standard. Version 6 and later use the Cloud Datastore API, so they run on App Engine Standard, App Engine Flex, Compute Engine or outside Google Cloud entirely.
How do I save and load an entity with Objectify?
Annotate the class with @Entity and its identifier with @Id, then use the fluent chain: ofy().save().entity(new Car("123123", "red")).now() to save, ofy().load().type(Car.class).id("123123").now() to load and ofy().delete().entity(c) to delete. The identifier can be a Long, a long or a String.
Does Objectify cache data in memcache?
Yes. Objectify can automatically cache your data in memcache for improved read performance, and it can also store polymorphic entities and run true polymorphic queries across a hierarchy.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/objectify-objectify)Was this useful?