ReleaseNotes - objectify/objectify GitHub Wiki

Release Notes

6.1.1

2024-01-03

  • Remove recently introduced constraint preventing ObjectifyService.init() from being called more than once. You shouldn't do this in application code, but it's common for tests.

6.1.0

2023-11-27

  • Objectify is easier to use with multiple datastores. Several methods have been deprecated; see UpgradeVersion6ToVersion61.
  • Add support for OR queries in composite filters
  • Make count() operations operate via server-side aggregation queries
  • Add sum(), avg(), and aggregate() [aggregation queries|AggregationQueries]
  • Add ofy().load().readTime() convenience method to perform queries with a ReadOption.readTime()
  • Add support for IN/!IN queries (technically this was already present; they were "enabled" by updating the google-cloud-datastore jar dependency).
  • Example applications have been added at https://github.com/objectify/objectify-examples

6.0.9

2022-10-05

  • Fix the .toLegacySafe() format to exactly match the values returned by 6.0.7 (and prior) when you are not using namespaces.

6.0.8

2022-09-27

  • Add support for not-equal filters (!=)
  • Add support for in and not-in filters (IN, !IN)
  • Add support for composite filters (.filter(Filter)). OR support will be enabled as soon as it is available in the underlying Google SDK.
  • Add .stream() method to queries (eg, ofy().load().type(Foo.class).stream().map(...)
  • Remove deprecated Key.getString() and Key.toWebSafeString() methods (use toUrlSafe() instead)
  • Change Key.getId() to return Long instead of long. It was documented to return 0 when not numeric, but actually threw NPE. Now returns null.
  • Address a potential race condition when using memcached (issue #451)
  • Accommodate namespaces in the toLegacyUrlSafe() value

WARNING: The toLegacyUrlSafe() value changed slightly in this version to allow for namespaces, even if you aren't using namespaces. We recommend you use 6.0.9 instead, which fixes this issue.

5.1.25

2021-04-23

  • Don't raise exceptions when memcache unreachable

6.0.7

2020-08-31

  • Improve the error message when loading data that is incompatible with the Java schema
  • Handle namespaces in legacy urlsafe string keys

6.0.6

2020-01-27

  • Fixed a bug that might "forget" the setting of ofy().cache(false) or ofy().namespace(...) in queries
  • Fixed several places that ofy().namespace() was being ignored (notably, when saving entities).
  • Automatically batch requests that exceed datastore request count limits (ie, 1000 reads or 500 writes).
  • Removed some long-deprecated methods.

6.0.5

2019-11-21

  • Add support for java.time.Instant

5.1.23

2019-07-29

  • Allow some control over MemcacheService instantiation.
  • Minor performance improvements.

6.0.4

2019-06-03

6.0.3

2019-01-29

  • Fix ofy().load().ids(long...) autoboxing problem.
  • Better error handling when reading old-style GAE string keys.

6.0.2

2018-09-20

  • Fix NPE when loading a collection field which has been previously stored as null in an entity (outside of Objectify).

6.0.1

2018-08-08

  • Fix error when trying to fetch more than 1000 keys at a time
  • Expose transaction handle
  • Better exception when an error occurs deserializing a @Serialize field

6.0

2018-04-06

If upgrading from a previous version, be sure to read UpgradeVersion5ToVersion6!

  • Made the cache implementation pluggable. See the constructor javadocs for ObjectifyFactory.

6.0b1

2018-02-15

  • You must call one of the overloads of ObjectifyService.init() during your application bootstrap (see UpgradeVersion5ToVersion6).
  • Creating a key from a string now accepts both the old-style ("agblahblahzxcpvouaw") and new-style urlsafe strings. You can generate them with Key.toUrlSafe() and Key.toLegacyUrlSafe().
  • Added ofy().load().option(...) to allow manual control of read consistency.

5.1.22

2018-01-29

  • POJOs fields with the @Serialize annotation now load correctly even when the underlying data type is ShortBlob. This can happen if you write the data outside of Objectify.

6.0a1

2017-12-23

This is the first version of Objectify that works with the new Google Cloud SDK. A list of changes is being maintained here: https://github.com/objectify/objectify/wiki/UpgradeVersion5ToVersion6

5.1.21

2017-07-06

  • Fixed issue causing the alsoLoad attribute of the @Subclass annotation to be ignored.

5.1.20

2017-07-03

  • Fixed bug in autoconversion of long unicode strings to Text, introduced in v5.1.18. The conversion limit is 1500 bytes not characters.

5.1.19

2017-06-28

  • Fixed performance bug causing memcache operations even for non-cacheable entities.

5.1.18

2017-06-28

  • At some point the max char limit for a String in the datastore was raised from 500 to 1500. Objectify's autoconvert-to-Text code now reflects this new higher limit.

5.1.17

2017-04-09

  • Optimized performance of query list(); async query was not being kicked off until first element accessed, which means it wasn't actually async at all. iterable() still has this undesirable behavior, although iterator() is properly async.

5.1.16

2017-03-16

  • Add ofy().mandatoryTransactions(true) to force users to create a transaction context for any save() or delete() operations. A useful defensive check.

5.1.15

2017-02-15

  • Expose constructor for EntityMemcache which allows MemcacheServiceFactory to be passed in. No behavioral changes.

5.1.14

2016-12-23

  • Ensure lifecycle events are fired in ofy().load().fromEntity()
  • Support fields of type Number

5.1.13

2016-05-25

  • Fixed bug causing collection fields to be ignored if they contain an empty nested subcollection.

5.1.12

2016-03-17

  • User code can now attach arbitrary data to transaction contexts through the TransactionImpl.bag property.

5.1.11

2016-03-07

  • ShortBlob properties are automatically converted to byte[] fields. byte[] fields are still saved as Blob.

5.1.10

2016-01-28

  • Added ofy().transact(Runnable) overload for Java8/retrolambda users

5.1.9

2015-11-08

  • With a few exceptions, @Load annotations no longer produce load effects in transactions. This reduces the tendency of @Load to bring in unwanted entity groups. Within transactions, @Parent relationships and @Load with explicitly activated groups will still force loading.
  • Deferred saves within @OnSave methods now work properly.
  • execute(TxnType.REQUIRES_NEW) now starts a new transaction like it's supposed to

5.1.8

2015-09-12

  • Relaxes requirement that a class have the @Entity annotation to be used to create a Key<?>. The kind will be the simplename of that class. Registered POJO entity classes still require the @Entity annotation; this only affects key creation.

5.1.7

2015-08-30

  • Classes marked @Entity which are stored embedded are allowed to have null keys. Previously, any @Id Long fields had to be populated with a real value. Now they are allowed to be null, which will leave the underlying EmbeddedEntity with a null key. The underlying datastore allows this. Note that unlike with top level entities, saving a null @Id does NOT autogenerate an id.

5.1.6

2015-08-09

  • Objectify.transactNew(count, work) was documented as # of tries but behaved as # of retries. Behavior now reflects documentation - # of tries.
  • Added missing overload for Query.filterKey(Object)
  • In transactions, only the first layer of fetching is performed asynchronously. All subsequent loads (via @Load annotations) are performed synchronously when the first layer of entities are materialized. This eliminates a rare edge case that produced spurious 'transaction closed' exceptions during transaction collisions. Outside of transactions, all fetches are performed asynchronously as normal.

5.1.5

2015-02-04

  • Fix NPE when doing kind() queries.
  • Fix NPE when a null value is projected.

5.1.4

2015-01-06

  • When an entity is explicitly saved or deleted, clear any pending deferred operations on that entity
  • Fix NPE when projecting properties with null values
  • Allow deleting of native Entity objects
  • Added ofy().load().kind(...) method
  • No longer need to de-hybridize IN and NOT queries

5.1.3

2014-12-01

  • Fixed a cross-compilation problem which produced a corrupt artifact for 5.1.2. No other changes.

5.1.2

2014-11-27

Don't use this version; the published artifact is corrupt.

  • Call superclass @OnSave methods before subclass @OnSave methods
  • Allow deferred save of entities with autogenerated ids.

5.1.1

2014-10-13

  • Fixed a problem with ObjectifyFilter re-entrancy that manifested when using dispatch.forward().
    • Note that this means you will not be warned if you leak Objectify contexts via ObjectifyService.begin()

5.1

2014-10-09

  • Added ofy().defer() and ofy().flush()
  • An exception will be thrown if you try to use Objectify without the ObjectifyFilter
  • A new method for using Objectify outside of normal request handling (unit tests, remote api, etc)

If you are using Objectify outside of a normal GAE http request (eg, unit tests or the the remote api), there is a new method you must invoke. See javadocs for ObjectifyService.run(). The old ObjectifyFilter.complete() method has been removed.

5.0.5

2014-09-29

IMPORTANT! Read the release notes for 5.0.

  • Fixed distinct() projection queries

5.0.4

2014-09-23

IMPORTANT! Read the release notes for 5.0.

  • Fixed a problem with projection of numeric types
  • Added method Key.toWebSafeString()
  • Trim the condition in Query.filterKey()

5.0.3

2014-06-08

IMPORTANT! Read the release notes for 5.0.

  • Implemented projection queries.
  • Fixed issue with collections as the value of an embedded map.
  • Bumped versions of GAE SDK and Guava.

5.0.2

2014-04-20

IMPORTANT! Read the release notes for 5.0.

  • Fix bug preventing @Id/@Parent fields from being defined in non-@Entity base classes.

5.0.1

2014-04-20

IMPORTANT! Read the release notes for 5.0.

  • Fix bug causing "no registered subclass found" when embedded class field has an annotation.
  • Added Query.orderKey()
  • ofy().delete().entities() now accepts anything keylike, not just entity objects

5.0

2014-04-13 IMPORTANT! Objectify v5 drops support for the old embedded object format. If you use embedded objects, you must follow the UpgradeVersion4ToVersion5 instructions or you may lose data.

  • Translation engine has been completely rewritten.
  • @Embed annotation has been dropped; any nested classes are embedded.
  • Collections of embedded objects can be nested without restriction.
  • Embedded objects support polymorphism and lifecycle methods.
  • Method handles are used to populate properties (better performance).
  • Query supports composite filters.

Some annotations have changed; read UpgradeVersion4ToVersion5.

4.1.3

2014-04-12

  • Requires Appengine SDK 1.8.3 or newer

  • Fix index contamination when batch saving multiple entities with nested indexes in the new format.

4.1.2

2014-04-05

  • Requires Appengine SDK 1.8.3 or newer

  • Fix bug loading old embed format when an embedded list contains null nested embedded objects.

IMPORTANT! Read the 4.1 release notes below

4.1.1

2014-03-31

  • Requires Appengine SDK 1.8.3 or newer

  • Fix bug loading new format when you have an @EmbedMap which contains EmbeddedEntity.

  • Fix bug loading new format when you have an array which contains EmbeddedEntity.

IMPORTANT! Read the 4.1 release notes below

4.1

2014-03-28

  • Requires Appengine SDK 1.8.3 or newer

  • GWT source removed from jar and moved to separate project. Fixes compile problems with GAE SDK 1.9.1.

  • Changes the storage format of @Embed objects

IMPORTANT! READ THIS!

Objectify is changing the native format in which @Embed objects are stored. Instead of creating dot-separated property names, Objectify 4.1 can store objects using the new EmbeddedEntity native storage type. You are strongly encouraged to migrate to this new storage type ASAP, because Objectify 5.0 will drop support for the old format entirely. The EmbeddedEntity format will allow many features that cannot be supported with the current codebase.

When loading entities Objectify 4.1 will automatically detect the format and read correctly. It defaults to writing the legacy format. If you call ObjectifyFactory.setSaveWithNewEmbedFormat(true), Objectify will write with the new format. To convert your entire database, set this flag and load+save every entity which has an @Embed structure.

If you use the new storage format, you MUST NOT revert to a previous version of Objectify or you will LOSE DATA. However, you must migrate all data to the new format before Objectify 5.0.

This does not affect you if you do not use @Embed. If you have any questions, post them to the Objectify Google Group.

4.0.1

2014-03-19

  • Requires Appengine SDK 1.8.3 or newer

  • Map and List objects returned from Objectify can now be serialized.

  • Added ability to set explicit memcache error handler.

  • Added Query.reverse() method.

  • @EmbedMap now allows keys to be of type Key<?> in addition to String.

  • Anything can convert to Text, just like anything can convert to String.

  • Builds with JDK1.7.

4.0

2014-02-07

  • Requires Appengine SDK 1.8.3 or newer

Since the first versions of Objectify, GAE's datastore API has expanded significantly with features (such as XG transactions and asynchrony) that fundamentally change how an API should work. Version 4 is a re-imagining of Objectify based on years of experience building GAE applications. The API and implementation have completely changed from Objectify v3; there's no way to produce a concise set of release notes. Please read all documentation from the beginning.

For v3 users, these two documents will help:

  • DesignObjectify4
  • UpgradeVersion3ToVersion4

Concise change notes will be maintained going forward.

3.1

2011-11-10

  • Requires Appengine SDK 1.6.0 or newer

Please read the release notes for 3.1 beta 1. In addition:

  • Always enables XG when starting a transaction on HRD
  • Memcache integration now uses SDK 1.6.0 batch CAS operations for efficiency
  • Added ObjectifyFactory.allocateIdRange()
  • Changed Key<?>.toWebSafeString() (introduced in 3.1b1) to getString()
  • Added a Key<?> constructor (and create() method) that takes a web safe string (ie getString())
  • Added optional converters for joda time and money classes
  • Added a varargs overload of Objectify.get(Key...)

3.1 beta 1

2011-10-13

  • Requires Appengine SDK 1.5.5 or newer

Note: The big change in 3.1 is that the memcache integration has been rewritten from scratch. On the plus side, the new cache will not go out of sync with the datastore, even under severe contention. On the down side, batch fetches are prohibitively slow. This will be resolved in a future version by the addition of batch CAS operations to the GAE SDK.

  • Added API for XG transactions
  • Completely rewritten cache code
  • Added Key>.toWebSafeString() and a constructor to reconstitute the Key>
  • Added ObjectifyFactory.allocateId() convenience method
  • Several internal API changes.

3.0.1

2011-09-08

  • Requires Appengine SDK 1.4.0 or newer

  • Added methods Query.chunkSize() and Query.prefetchSize()

  • Experimental support for @Embedded Maps

  • Added a TimeZoneConverter so you can have TimeZone fields

  • Added a BigDecimalLongConverter which is not enabled by default

3.0

2011-04-22

  • Requires Appengine SDK 1.4.0 or newer

IMPORTANT! Read the release notes for beta1 and beta2, in particular the note about breaking Key> serialization. If you have **serialized** Key> objects into persistent stores, this will affect you. Also, you will not be able to construct Key<?> objects from client-side GWT.

  • Fixed NPE when fetching polymorphic entities not in the database.
  • Fixed NPE when fetching collection field with raw type (missing generics).

3.0 beta 2

2011-04-04

  • Requires Appengine SDK 1.4.0 or newer

  • Implemented Polymorphic persistence

  • Key> implementation changed - this WILL BREAK KEY SERIALIZATION. If you have serialized keys in a persistent structure, read the discussion of this issue on the mailing list. This only affects Key> in @Serialized fields; simple Key> properties and @Embedded Key>s are fine.

  • Fields now receive their @Indexed/@Unindexed default state from the class they are declared on rather than the final class in the inheritance hierarchy. This is a potential breaking change, although previous behavior was undocumented.

  • Added a Query.fetch() method to produce an async Iterable

  • Better error message if you try to register a nonstatic inner class

  • Loading embedded collections with a null value for the property itself no longer throws an exception.

  • Added IfEmpty and IfNotEmpty conditions

  • A number of internal APIs changed to support polymorphism.

3.0 beta 1

2011-02-28

  • Requires Appengine SDK 1.4.0 or newer

  • Implemented asynchronous operations on AsyncObjectify

  • Breaking change: Moved all classes in com.googlecode.objectify.helper to com.googlecode.objectify.util, including DAOBase

  • Significant internal changes to support async API.

2.2.3

2010-12-13

  • Requires Appengine SDK 1.4.0 or newer

  • Added pluggable system for managing type conversions

  • Unwraps InvocationTargetExceptions in lifecycle callbacks

  • Made ObjectifyOpts.clone() public

  • Fixed bug when filtering by enums

  • Added a "Monotonic" helper class

2.2.2

2010-10-21

  • Requires Appengine SDK 1.3.8 or newer

  • Deprecated Query.countAll(), added Query.count() method which behaves better.

  • Deprecated Query.cursor(); added Query.startCursor() and Query.endCursor().

  • Added Query.clone()

  • Allows null @Parent keys.

  • Now handles java.sql.Date

  • Ignores synthetic fields (should make Groovy happier)

  • Now respects @Indexed/@Unindexed on entity base classes.

  • Added overrideable createDefaultOpts() method to ObjectifyFactory. Added clone() method to ObjectifyOpts.

  • @Id and @Parent fields are now included when you embed an entity in another entity.

  • Fixed a bug related to fields whose type base class name overlapped with entity names (eg, User)

2.2.1

2010-06-01

  • Requires Appengine SDK 1.3.2 or newer

  • Added typesafe ObjectifyFactory.allocateIds() methods.

  • Enums are persisted using the .name() method rather than .toString()

  • Added varargs versions of Objectify.put() and Objectify.get()

  • DAOBase now lets you use ObjectifyOpts

2.2

2010-04-22

  • Requires Appengine SDK 1.3.2 or newer

  • Added ObjectifyOpts parameter to begin()

  • Added optional session cache

  • Fixed automatic byte[] to Blob conversion

  • Added Query.list() and Query.listKeys() methods

  • Fixed filtering with IN operator on key and id columns

  • Lifecycle callbacks (@PostLoad and @PrePersist) can now take Objectify and/or Entity parameters

  • Removed the datastore retry mechanism - this is now built into the appengine SDK.

2.1

2010-03-25

  • Requires Appengine SDK 1.3.1 or newer

  • Changed return type of Objectify.get(Class<? extends T> clazz, Iterable<S> idsOrNames) to Map<S, T> rather than Map<Key<T>, T>. This is a breaking change

  • Added support for partial index conditions to @Indexed and @Unindexed

  • Added @NotSaved (with conditions)

  • Added @AlsoLoad as replacement for @OldName

  • Deprecated @OldName

  • Added Objectify.getFactory() method

  • Added wrapper helper classes for Objectify, Query, and QueryResultIterator

2.0.2

2010-02-25

  • Requires Appengine SDK 1.3.1 or newer

  • Added @Unindexed and @Indexed class and field support

  • Fixed bugs in query Cursor and limit() support.

2.0.1

2010-02-18

  • Requires Appengine SDK 1.3.1 or newer

  • Added Cursor support

  • Added @PostLoad and @PrePersist callbacks

2.0

2010-02-10

  • Requires Appengine SDK 1.3.0 or newer

  • See 2.0rc1 and 2.0b1 release notes for significant changes since 1.0.3.

  • Changed ObjectifyFactory.createKey() to slightly-different ObjectifyFactory.getKey() and removed createKey() from ObjectifyService.

2.0 rc 1

2010-02-09

  • Requires Appengine SDK 1.3.0 or newer

  • Adds memcache integration (write-through, transaction safe, negative caching, custom class expiration) with a @Cached annotation.

2.0 beta 1

2010-02-07

  • Requires Appengine SDK 1.3.0 or newer

  • Completely new Query API.

  • OKey> has been renamed to Key>

  • Added @Embedded classes, collections, and arrays

  • Added GWT versions of all basic datastore types (Email, Link, GeoPt, etc)

  • Fields using the transient keyword will now be persisted. The @Transient annotation is now the only way to tell Objectify to ignore a field.

  • New architecture and many more unit tests!

1.0.3

2010-01-29

  • Requires Appengine SDK 1.3.0 or newer

  • Fixed a bug in batch delete.

1.0.2

2010-01-26

  • Requires Appengine SDK 1.3.0 or newer

  • Entity superclasses now processed correctly.

  • OKey now serializes properly in GWT.

  • Fixed classloader exception when using FetchOptions with datastore retries.

  • Better error msg if entity missing no-args constructor.

1.0.1

2010-01-22

  • Requires Appengine SDK 1.3.0 or newer

  • Added support for Enum types

  • Fixed OPreparedQuery.asSingle() when resultset was empty

  • Added full support for the common collection types

1.0

2010-01-13

  • Requires Appengine SDK 1.3.0 or newer

  • Initial release.

⚠️ **GitHub.com Fallback** ⚠️