All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.objectify.Objectify Maven / Gradle / Ivy

There is a newer version: 6.1.2
Show newest version
package com.googlecode.objectify;

import com.google.appengine.api.datastore.ReadPolicy.Consistency;
import com.google.appengine.api.datastore.Transaction;
import com.googlecode.objectify.cmd.Deferred;
import com.googlecode.objectify.cmd.Deleter;
import com.googlecode.objectify.cmd.Loader;
import com.googlecode.objectify.cmd.Saver;

/**
 * 

This is the main "business end" of Objectify. It lets you load, save, and delete your typed POJO entities.

* *

{@code Objectify} instances are obtained by calling the static method {@code ObjectifyService.ofy()}. This method * will always provide the correct {@code Objectify} instance for a given transactional context. You can run * transactions by calling {@code Objectify.transact()} or {@code Objectify.transactNew()}; calling {@code ObjectifyService.ofy()} * within {@code Work.run()} will produce the correct {@code Objectify} instance associated with the correct transaction.

* *

Objectify instances are immutable but they are NOT thread-safe. The instance contains * a session cache of entities that have been loaded from the instance. You should never access an Objectify * from more than one thread simultaneously.

* * @author Jeff Schnitzer */ public interface Objectify { /** *

Start a load command chain. This is where you begin for any request that fetches data from * the datastore: gets and queries.

* *

A quick example: * {@code Map, Thing> things = ofy().load().type(Thing.class).parent(par).ids(123L, 456L);}

* *

All command objects are immutable; this method returns a new object rather than modifying the * current command object.

* * @return the next step in the immutable command chain. */ Loader load(); /** *

Start a save command chain. Allows you to save (or re-save) entity objects. Note that all command * chain objects are immutable.

* *

Saves do NOT cascade; if you wish to save an object graph, you must save each individual entity.

* *

A quick example: * {@code ofy().save().entities(e1, e2, e3).now();}

* *

All command objects are immutable; this method returns a new object rather than modifying the * current command object.

* * @return the next step in the immutable command chain. */ Saver save(); /** *

Start a delete command chain. Lets you delete entities or keys.

* *

Deletes do NOT cascade; if you wish to delete an object graph, you must delete each individual entity.

* *

A quick example: * {@code ofy().delete().entities(e1, e2, e3).now();}

* *

All command objects are immutable; this method returns a new object rather than modifying the * current command object.

* * @return the next step in the immutable command chain. */ Deleter delete(); /** *

Start a deferred command chain, which lets you make multiple save or delete calls on a single * entity without incurring multiple datastore operations. Deferred operations are executed at the * end of a unit-of-work (transaction, or http request if not in a transaction).

* *

Deferred operations are reflected in the session cache immediately. However query operations * may not reflect these changes. For example, newly indexed entities may not show up, even with * an otherwise strongly consistent ancestor query. This should not be surprising since the actual * save operation has not occurred yet.

* *

In the case of deferred save() and delete() operations on the same entity, the last one wins.

* * @return the next step in the immutable command chain. */ Deferred defer(); /** * Obtain the ObjectifyFactory from which this Objectify instance was created. * * @return the ObjectifyFactory associated with this Objectify instance. */ ObjectifyFactory factory(); /** *

Provides a new Objectify instance with the specified Consistency. Generally speaking, STRONG consistency * provides more consistent results more slowly; EVENTUAL consistency produces results quickly but they * might be out of date. See the * Appengine Docs * for more explanation.

* *

The new instance will inherit all other characteristics (transaction, cache policy, session cache contents, etc) * from this instance.

* *

All command objects are immutable; this method returns a new object rather than modifying the * current command object.

* * @param policy the consistency policy to use. STRONG load()s are more consistent but EVENTUAL load()s * are faster. * @return a new immutable Objectify instance with the consistency policy replaced */ Objectify consistency(Consistency policy); /** *

Provides a new Objectify instance with a limit, in seconds, for datastore calls. If datastore calls take longer * than this amount, a timeout exception will be thrown.

* *

The new instance will inherit all other characteristics (transaction, cache policy, session cache contents, etc) * from this instance.

* *

All command objects are immutable; this method returns a new object rather than modifying the * current command object.

* * @param value - limit in seconds, or null to indicate no deadline (other than the standard whole request deadline of 30s/10m). * @return a new immutable Objectify instance with the specified deadline */ Objectify deadline(Double value); /** *

Provides a new Objectify instance which uses (or doesn't use) a 2nd-level memcache. * If true, Objectify will obey the @Cache annotation on entity classes, * saving entity data to the GAE memcache service. Fetches from the datastore * for @Cache entities will look in the memcache service first. This cache * is shared across all versions of your application across the entire GAE * cluster.

* *

Objectify instances are cache(true) by default.

* *

All command objects are immutable; this method returns a new object rather than modifying the * current command object.

* * @return a new immutable Objectify instance which will (or won't) use the global cache */ Objectify cache(boolean value); /** *

Get the underlying transaction object associated with this Objectify instance. You typically * do not need to use this; use transact() instead.

* *

Note that this is *not* the same as {@code DatastoreService.getCurrentTransaction()}, * which uses the Low-Level API's implicit transaction management. Every transactional {@code Objectify} * instance is associated with a specific {@code Transaction} object.

* * @return the low-level transaction associated with this Objectify instance, * or null if no transaction is associated with this instance. */ Transaction getTransaction(); /** *

If you are in a transaction, this provides you an objectify instance which is outside of the * current transaction and works with the session prior to the transaction start. Inherits any * settings (consistency, deadline, etc) from the present Objectify instance.

* *

If you are not in a transaction, this simply returns "this".

* *

This allows code to quickly "escape" a transactional context for the purpose of loading * manipulating data without creating or affecting XG transactions.

* *

All command objects are immutable; this method returns a new object instead of modifying the * current command object.

* * @return an immutable Objectify instance outside of a transaction, with the session as it was before txn start. */ Objectify transactionless(); /** *

Executes work in a transaction. If there is already a transaction context, that context will be inherited. * If there is not already a transaction context, a new transaction will be started.

* *

Within {@code Work.run()}, obtain the correct transactional {@code Objectify} instance by calling * {@code ObjectifyService.ofy()}

* *

ConcurrentModificationExceptions will cause the transaction to repeat as many times as necessary to * finish the job. Work MUST idempotent.

* * @param work defines the work to be done in a transaction. If this method started a new transaction, it * will be committed when work is complete. If transactional context was inherited, no commit is issued * until the full transaction completes normally. * @return the result of the work */ R transact(Work work); /** *

Executes work in a new transaction. Note that this is equivalent to {@code transactNew(Integer.MAX_VALUE, work);}

* *

ConcurrentModificationExceptions will cause the transaction to repeat as many times as necessary to * finish the job. Work MUST idempotent.

* *

Within {@code Work.run()}, obtain the new transactional {@code Objectify} instance by calling {@code ObjectifyService.ofy()}

* * @param work defines the work to be done in a transaction. After the method exits, the transaction will commit. * @return the result of the work */ R transactNew(Work work); /** *

Executes the work in a new transaction, repeating up to limitTries times when a ConcurrentModificationException * is thrown. This requires your Work to be idempotent; otherwise limit tries to 1. * *

Within {@code Work.run()}, obtain the new transactional {@code Objectify} instance by calling {@code ObjectifyService.ofy()}

* * @param work defines the work to be done in a transaction. After the method exits, the transaction will commit. * @return the result of the work */ R transactNew(int limitTries, Work work); /** *

Executes the work with the transactional behavior defined by the parameter txnType. This is very similar * to EJB semantics. The work can inherit a transaction, create a new transaction, prevent transactions, etc.

* *

This method principally exists to facilitate implementation of AOP interceptors that provide EJB-like behavior. * Usually you will call {@code transact()} or {@code transactNew()} when writing code.

* *

Note that ConcurrentModificationExceptions will cause the transaction to repeat as many times as necessary to * finish the job. Work MUST idempotent.

* *

Within {@code Work.run()}, obtain the correct {@code Objectify} instance by calling {@code ObjectifyService.ofy()}

* * @param txnType defines what kind of transaction context the work should be executed in. * @param work defines the work to be done; possibly in a transaction, possibly not as defined by txnType * @return the result of the work */ R execute(TxnType txnType, Work work); /** * Synchronously flushes any deferred operations to the datastore. Objectify does this for you at the end * of transactions and requests, but if you need data to be written immediately - say, you're about to perform * a strongly-consistent ancestor query and you need to see the updated indexes immediately - you can call this * method. If there are no deferred operations, this does nothing. */ void flush(); /** *

Clears the session; all subsequent requests (or Ref.get() calls) will go to the datastore/memcache * to repopulate the session. This should rarely, if ever be necessary. Note that if you iterate query results * you should only perform this action on chunk boundaries, otherwise performance will suffer. This is a "use * only if you really know what you are doing" feature.

*/ void clear(); /** * @return true if the key has been loaded into the session; false if loading the key would result in a datastore * (or memcache) fetch. */ boolean isLoaded(Key key); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy