Skip to content

Latest commit

 

History

History
267 lines (187 loc) · 10.3 KB

File metadata and controls

267 lines (187 loc) · 10.3 KB

  1. summary Loading, Saving, and Deleting Data
<wiki:toc max_depth="3"></wiki:toc>

Table of Contents

The Instance

All datastore operations begin with an instance of (javadoc). An instance holds the complete state of your persistence session:

  * A transaction context, if present
  * A cache of entity objects loaded in the current session
  * Parameters for deadline, consistency setting, and caching

  • An instance should be used from a single thread only.* It is a cheap throwaway object that represents a session of activity. Typically you will re-use a single instance through a request, except when you begin transactions.

Obtaining an Instance

The preferred way to obtain an instance is to call a static method:

To keep the typing to a minimum, we recommend a static import:

will always return the correct instance for your thread and transaction context and provides you with an "always available" persistence context without having to pass extra parameters to your business methods. The instance returned by will change when you enter and exit transactions. Be sure to install the so that the last instance is cleaned up at the end of a request.

As a general practice, we recommend *_not_* holding on to instance variables:

Consistently using eliminates potential confusion when working with multiple layers of transaction depth. This will be discussed in more detail in the section on [Transactions].

Altering Parameters

instances maintain immutable parameter state:


Any given instance has immutable state, but methods can be called to create new instances with different parameters:

The Session Cache

Each instance holds a cache of entities which have been loaded in that session. This prevents subsequent loads within that session from needing to go out to the datastore. The cache holds entity instances and (with the exception of transactions) will consistently return the same actual object instance.

This cache is separate from the global memcache enabled/disabled with the annotation and the parameter.

The session cache is always enabled. If you iterate through large numbers of entities, this session cache may cause memory issues. You can clear the cache at intervals by calling:

Loading

provides a variety of ways to load entities from the datastore. They all begin with a command chain started by . Note that all operations are asynchronous until you manifest an actual entity POJO; all the , , and interfaces hide the asynchrony.

This covers the type of requests that all translate into a get-by-key in the datastore. For another way to load data, see [Queries].

Load Groups

When you use Ref fields to establish relationships between entities, you can use the annotation to automatically retrieve an object graph using the optimal number of batch fetches. However, you do not always want to load an entire graph.

Objectify provides _load groups_, inspired by Jackson's Json Views. Here is the simplest usage:

Here is a more complicated example:

You can combine required and 'unless', and also specify multiple groups:

Saving

Be careful when saving entities with an autogenerated Long field. A synchronous save() will populate the generated id value on the entity instance. An asynchronous save() will not; the operation will be pending until the async operation is completed.

Deleting

Deferring Operations

All of the previously mentioned operations invoke datastore operations immediately - including (especially!) the asynchronous ones. This is inconvenient when you may end up conditionally making several changes to an entity. For example, when synchronizing multiple fields of an entity, you typically have to track a 'changed' state:

Deferred operations are delayed until the end of a unit-of-work. That is, a transaction commit or the end of a request. Here is the above using deferred operations:

This will produce one datastore save at the end of the unit-of-work.

In the case of both `save()` and `delete()` operations deferred for the same entity, the last operation wins.