Class ObjectifyImpl<O extends Objectify>
public class ObjectifyImpl<O extends Objectify> extends Object implements Objectify, Cloneable
Implementation of the Objectify interface. This is also suitable for subclassing; you can return your own subclass by overriding ObjectifyFactory.begin().
Note we *always* use the AsyncDatastoreService methods that use transactions to avoid the confusion of implicit transactions.
- Author:
- Jeff Schnitzer
-
Field Summary
FieldsModifier and TypeFieldDescriptionprotected boolean
Our optionsprotected com.google.appengine.api.datastore.ReadPolicy.Consistency
protected Double
protected ObjectifyFactory
The factory that produced usprotected boolean
protected Transactor<O>
-
Constructor Summary
ConstructorsConstructorDescriptionObjectifyImpl(ObjectifyImpl<O> other)
Copy constructorObjectifyImpl(ObjectifyFactory fact)
-
Method Summary
Modifier and TypeMethodDescriptioncache(boolean value)
Provides a new Objectify instance which uses (or doesn't use) a 2nd-level memcache.void
clear()
Clears the session; all subsequent requests (or Ref>.get() calls) will go to the datastore/memcache to repopulate the session.protected ObjectifyImpl<O>
clone()
consistency(com.google.appengine.api.datastore.ReadPolicy.Consistency value)
Provides a new Objectify instance with the specified Consistency.protected com.google.appengine.api.datastore.AsyncDatastoreService
Make a datastore service config that corresponds to our options.protected com.google.appengine.api.datastore.DatastoreServiceConfig
Make a datastore service config that corresponds to our options.protected WriteEngine
Use this once for one operation and then throw it awayProvides a new Objectify instance with a limit, in seconds, for datastore calls.defer()
Start a deferred command chain, which lets you make multiple save or delete calls on a single entity without incurring multiple datastore operations.delete()
Start a delete command chain.<R> R
Executes the work with the transactional behavior defined by the parameter txnType.factory()
Obtain the ObjectifyFactory from which this Objectify instance was created.void
flush()
Synchronously flushes any deferred operations to the datastore.boolean
getCache()
protected Session
Get the underlying transaction object associated with this Objectify instance.boolean
load()
Start a load command chain.protected Object
makeFilterable(Object value)
Translates the value of a filter clause into something the datastore understands.mandatoryTransactions(boolean value)
Provides a new Objectify instance which throws an exception whenever save() or delete() is called from outside a transaction context.save()
Start a save command chain.<R> R
Executes work in a transaction.void
Exactly the same behavior as the Work version, but doesn't return anything.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.<R> R
transactNew(int limitTries, Work<R> work)
Executes the work in a new transaction, repeating up to limitTries times when a ConcurrentModificationException is thrown.<R> R
transactNew(Work<R> work)
Executes work in a new transaction.
-
Field Details
-
factory
The factory that produced us -
cache
protected boolean cacheOur options -
consistency
protected com.google.appengine.api.datastore.ReadPolicy.Consistency consistency -
deadline
-
mandatoryTransactions
protected boolean mandatoryTransactions -
transactor
-
-
Constructor Details
-
ObjectifyImpl
-
ObjectifyImpl
Copy constructor
-
-
Method Details
-
factory
Description copied from interface:Objectify
Obtain the ObjectifyFactory from which this Objectify instance was created. -
load
Description copied from 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:
Map<Key<Thing>, 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.
-
save
Description copied from interface:Objectify
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:
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.
-
delete
Description copied from interface:Objectify
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:
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.
-
defer
Description copied from interface:Objectify
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.
-
consistency
Description copied from interface:Objectify
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.
- Specified by:
consistency
in interfaceObjectify
- Parameters:
value
- the consistency policy to use. STRONG load()s are more consistent but EVENTUAL load()s are faster.- Returns:
- a new immutable Objectify instance with the consistency policy replaced
-
deadline
Description copied from interface:Objectify
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.
-
cache
Description copied from interface:Objectify
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.
-
mandatoryTransactions
Description copied from interface:Objectify
Provides a new Objectify instance which throws an exception whenever save() or delete() is called from outside a transaction context. This is a reasonable sanity check for most business workloads; you may wish to enable it globally by overriding ObjectifyFactory.begin() to twiddle this flag on the returned object.
Objectify instances are mandatoryTransactions(false) by default.
All command objects are immutable; this method returns a new object rather than modifying the current command object.
- Specified by:
mandatoryTransactions
in interfaceObjectify
- Returns:
- a new immutable Objectify instance which will (or won't) require transactions for save() and delete().
-
transactionless
Description copied from interface:Objectify
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.
- Specified by:
transactionless
in interfaceObjectify
- Returns:
- an immutable Objectify instance outside of a transaction, with the session as it was before txn start.
-
clone
-
getTransaction
Description copied from interface:Objectify
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
DatastoreService.getCurrentTransaction()
, which uses the Low-Level API's implicit transaction management. Every transactionalObjectify
instance is associated with a specificTransaction
object.- Specified by:
getTransaction
in interfaceObjectify
- Returns:
- the low-level transaction associated with this Objectify instance, or null if no transaction is associated with this instance.
-
execute
Description copied from interface:Objectify
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
transact()
ortransactNew()
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
Work.run()
, obtain the correctObjectify
instance by callingObjectifyService.ofy()
-
transact
Description copied from interface:Objectify
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
Work.run()
, obtain the correct transactionalObjectify
instance by callingObjectifyService.ofy()
ConcurrentModificationExceptions will cause the transaction to repeat as many times as necessary to finish the job. Work MUST idempotent.
- Specified by:
transact
in interfaceObjectify
- Parameters:
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.- Returns:
- the result of the work
-
transact
Description copied from interface:Objectify
Exactly the same behavior as the Work version, but doesn't return anything. Convenient for Java8 so you don't have to return something from the lambda.
-
transactNew
Description copied from interface:Objectify
Executes work in a new transaction. Note that this is equivalent to
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
Work.run()
, obtain the new transactionalObjectify
instance by callingObjectifyService.ofy()
- Specified by:
transactNew
in interfaceObjectify
- Parameters:
work
- defines the work to be done in a transaction. After the method exits, the transaction will commit.- Returns:
- the result of the work
-
transactNew
Description copied from interface:Objectify
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
Work.run()
, obtain the new transactionalObjectify
instance by callingObjectifyService.ofy()
- Specified by:
transactNew
in interfaceObjectify
- Parameters:
limitTries
- is the max # of tries. Must be > 0. A value of 1 means "try only once".work
- defines the work to be done in a transaction. After the method exits, the transaction will commit.- Returns:
- the result of the work
-
clear
public void clear()Description copied from interface:Objectify
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.
-
createDatastoreServiceConfig
protected com.google.appengine.api.datastore.DatastoreServiceConfig createDatastoreServiceConfig()Make a datastore service config that corresponds to our options. -
createAsyncDatastoreService
protected com.google.appengine.api.datastore.AsyncDatastoreService createAsyncDatastoreService()Make a datastore service config that corresponds to our options. -
createWriteEngine
Use this once for one operation and then throw it away- Returns:
- a fresh engine that handles fundamental datastore operations for saving and deleting
-
makeFilterable
Translates the value of a filter clause into something the datastore understands. Key> goes to native Key, entities go to native Key, java.sql.Date goes to java.util.Date, etc. It uses the same translation system that is used for standard entity fields, but does no checking to see if the value is appropriate for the field.
Unrecognized types are returned as-is.
A future version of this method might check for type validity.
- Returns:
- whatever can be put into a filter clause.
-
getSession
-
getCache
public boolean getCache()- Returns:
- true if cache is enabled
-
isLoaded
-
flush
public void flush()Description copied from interface:Objectify
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.
-