Google App Engine Persistence – Generic repositories with Objectify

No Comments

Google’s App Engine is a platform as a service (PAAS) offered by Google. Any servlet-based web application can be deployed there with limitations due to the cloud character of the environment:
Instances can be deployed and undeployed at any time. Instances can run in very different locations. A user communicating now with an application deployed in the USA may be communicating the next second with an application deployed in Ireland, without notice.

One limitation is that a common relational database cannot work in such a very dynamic environment. That’s why Google App Engine has a table-based NoSQL solution called BigTable.

Data access in the Google App Engine

Google App Engine offers a low level API for Java, which is not supposed to be interacted with from an application directly, but more to build new adaptors. On a higher level App Engine offers an integration with JPA and JDO, but with limitations due to the fact that BigTable is not a relational database.

We decided to use a third alternative: Objectify.

With Objectify you can persist typed POJOs, use a simple transaction model, typed keys and queries. Objectify has a small footprint and doesn’t pretend to be working with a relational database.

Objectify entity

Here we have a very simple entity.

public class UserObjectify {
	private Long id;
	private String name;
	private AddressObjectify address;
	private Key role;

@Indexed and @Unindexed decide about indexing data in BigTable. With @Embedded you can persist whole objects with this entity. These objects have to be annotated with @Embeddable, it’s not possible to search for them independently. An association gets persisted by storing a Key of the type of the associated object.

Get, put, delete and query with Objectify

The class Objectify offers methods for getting, putting, deleting and querying entities. The ObjectifyFactory can be used for creating an Objectify object. It accesses the DatastoreService, which is always present in Google App Engine. We use the helper class DAOBase as a base for our repositories. This class is part of the Objectify module and grants access to a lazy initialized Objectify object via the ofy() method. This method can be used as follows.


UserObjectify userObjectify = ofy().get(UserObjectify.class, id);






List users = ofy().query(UserObjectify.class)
    .filter("role", new Key(RoleObjectify.class, roleId)).list();

Via the Query object you have different possibilities for querying.

Mismatch between domain and persistence classes

Our domain class User looks like this:

public class User {
	private Long id;
	private String name;
	private Address address;
	private Role role;

First of all comes to mind that associations are not reflected by keys but by the real objects, in this case of type Role. Together with the fact that we don’t want the proprietary Objectify annotations in our domain it’s clear that we need two classes.


Our domain has to stay clean, that’s why our repositories only take domain classes as parameters, no Objectify persistence classes. We create a BaseRepository interface containing the methods that all entities have in common. EntityAggregateRoot is the common interface of all domain entities.

public interface EntityAggregateRoot {
	Long getId();
	void setId(Long id);
public interface BaseRepository {
	Long put(T entity);
	T get(Long id);
	void delete(T entity);

Mapping between domain and persistence classes

EntityAggregateRootObjectify is the common interface of all Objectify entities.

public interface EntityAggregateRootObjectify {
	Long getId();
	void setId(Long id);

The interface Mapping gets implemented for every couple of domain and Objectify classes for mapping the data between them. These classes stay really simple.

public interface Mapping {
	T fromObjectify(U entityObjectify);
	U toObjectify(T entity);

Parent class for repositories: AbstractRepository

AbstractRepository extends DAOBase for accessing the Objectify object ofy(). It implements BaseRepository. The entity classes and the mapping class are generic. Since we need the concrete Objectify entity class (for example UserObjectify) for get() and query(), it is set via constructor called by the subclass.

public abstract class AbstractRepository>
		extends DAOBase implements BaseRepository {
	protected V mapping;
	private Class<u> entityAggregateRootObjectifyClass;
	protected AbstractRepository(V mapping,
			Class<u> entityAggregateRootObjectifyClass) {
		this.mapping = mapping;
		this.entityAggregateRootObjectifyClass = entityAggregateRootObjectifyClass;

In the method put() you see how the mapping between domain and Objectify entity is done. Afterwards the mapped entity is persisted by the ofy() object. Finally the ID is set in the domain entity and given back to the caller. The method delete() works in a similar manner.

	public Long put(T entity) {
		U entityObjectify = mapping.toObjectify(entity);
		return entityObjectify.getId();
	public void delete(T entity){
		U entityObjectify = mapping.toObjectify(entity);

The method get() loads the designated object and converts it to a domain entity. The method handleAssociations() can be overriden by subclasses for loading associations. We’ll see how that works in ObjectifyUserRepository later in this post.

	public T get(Long id) {
		U entityObjectify = ofy().get(entityAggregateRootObjectifyClass, id);
		T entity = mapping.fromObjectify(entityObjectify);
		return this.handleAssociations(entity, entityObjectify);
	protected T handleAssociations(T entity, U entityObjectify) {
		return entity;

All methods of the BaseRepository interface are implemented now. For supporting queries in subclasses we’ll add another method working with a callback interface. With the QueryCallback a subclass can compose any query which will be executed by the following method, including mapping.

	protected List getEntities(QueryCallback<u> queryCallback) {
		List entityList = new ArrayList();
		Query<u> query = ofy().query(entityAggregateRootObjectifyClass);
		query = queryCallback.manipulateQuery(query);
		for (U entityObjectify : query) {
			T entity = mapping.fromObjectify(entityObjectify);
			entityList.add(this.handleAssociations(entity, entityObjectify));
		return entityList;
	protected interface QueryCallback<u> {
		public Query<u> manipulateQuery(Query<u> query);

Implementation: ObjectifyUserRepository

The implemenation for the entity User is quite short now because get(), put() and delete() are covered by the parent class. We just add a special query method for querying all users with a certain role. The method handleAssociations resolves the association from User to Role by loading the role with the RoleRepository.

public class ObjectifyUserRepository extends
		AbstractRepository&lt;User, UserObjectify, UserMapping&gt;{
	static {
	private RoleRepository roleRepository;
	public ObjectifyUserRepository(UserMapping userMapping, RoleRepository roleRepository) {
		super(userMapping, UserObjectify.class);
		this.roleRepository = roleRepository;
	public List findUserByRoleId(final Long roleId) {
		return this.getEntities(new QueryCallback() {
			public Query manipulateQuery(
					Query query) {
				return query.filter("role", new Key(RoleObjectify.class, roleId));
	protected User handleAssociations(User entity,
			UserObjectify entityObjectify) {
		if (entityObjectify.getRole() != null) {
		return entity;


Objectify is easy to use and brings less overhead than JDO and JPA, which can be used in Google App Engine in a limited way.

In our application we separated data access and domain in a clear way. Objectify is only used and only visible there, where we really need it.

By creating the parent class AbstractRepository we avoid any code duplication and make it easy to implement new repositories for new entities.


Your email address will not be published. Required fields are marked *