Home - objectify/objectify GitHub Wiki

Introduction to Objectify

Objectify is a Java data access API specifically designed for the Google App Engine datastore. Its goals are to:

  • Be easy to learn and understand.
  • Support all native datastore features in an intuitive, human-friendly way.
  • Model sophisticated, strongly-typed, polymorphic data structures.
  • Enable modular, EJB-like transactional logic.
  • Increase performance and decrease cost through smart, transaction-aware caching.
  • Allow major schema migrations "in-place" with zero downtime.
  • Seamlessly coexist with other datastore tools: the Java Low-Level API, JDO/JPA, Twig, Go, Python DB and NDB.

Objectify provides a level of abstraction that is high enough to be convenient, but low enough not to obscure the key/value nature of the datastore. It is intended to be a Goldilocks API - not too low level, not too high level, just right.

Overview

If you are new to Google App Engine, start with Concepts

This is a quick tour of what using Objectify looks like, intended to give you a taste of the framework. Full explanations can be found later in the documentation.

Defining Entities

A simple entity:

import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Index;

@Entity
public class Car {
    @Id Long id;
    @Index String license;
    int color;
}

Somewhat more complicated:

import com.googlecode.objectify.annotation.AlsoLoad;
import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.IgnoreSave;
import com.googlecode.objectify.annotation.Load;
import com.googlecode.objectify.annotation.OnLoad;

@Entity
@Cache
public class Motorcycle {
    @Id String vin;
    @Load List<Ref<Person>> owners = new ArrayList<Ref<Person>>();
    @AlsoLoad("colour") int color;
    @IgnoreSave boolean ktm;

    @OnLoad public void onLoad() {
        if (ktm)
            color = ORANGE;
    }
}

Basic Operations

import static com.googlecode.objectify.ObjectifyService.ofy;

Car porsche = new Car("2FAST", RED);
ofy().save().entity(porsche).now();    // async without the now()

assert porsche.id != null;    // id was autogenerated

// Get it back
Result<Car> result = ofy().load().key(Key.create(Car.class, porsche.id));  // Result is async
Car fetched1 = result.now();    // Materialize the async value

// More likely this is what you will type
Car fetched2 = ofy().load().type(Car.class).id(porsche.id).now();

// Or you can issue a query
Car fetched3 = ofy().load().type(Car.class).filter("license", "2FAST").first().now();

// Change some data and write it
porsche.color = BLUE;
ofy().save().entity(porsche).now();    // async without the now()

// Delete it
ofy().delete().entity(porsche).now();    // async without the now()
⚠️ **GitHub.com Fallback** ⚠️