ObjectBox Queries

ObjectBox queries return persisted objects that match user defined criteria. With ObjectBox db you use the QueryBuilder class to specify criteria and create Query objects. The Query class will actually run the query and return matching objects.


The QueryBuilder<T> class lets you build custom queries for your entities. It is used along with the properties class generated for each entity.

This example assumes an entity class User and its generated properties class User_.

Simple condition example: Query for all users with the first name “Joe”:

Multiple conditions example: Get users with the first name “Joe” that are born later than 1970 and whose last name starts with “O”.

For an overview of all available criteria, please refer to the QueryBuilder class. We will extend the documentation here soon.


Queries are created (and not yet executed) by calling build() on the QueryBuilder.

Finding objects

There are a couple of find methods to retrieve objects matching the query:

To return all entities matching the query simply call find().

To only return the first result, use findFirst().

If you expect a unique result call findUnique() instead. It will give you a single result or null, if no matching entity was found and throw an exception if there was more than one result.

Reusing Queries and Parameters

Query objects allow you to execute queries multiple times in an efficient way. To make queries more reusable all criteria values you previously set in the QueryBuilder can be changed. That’s why we call them query parameters.

Let’s look at example:

Here we used one query object to find two sets of users, each with a specific first name. Note that we still have to initialize the value for the firstName property when building the query. Because we always overwrite the value using .setParameter()  we can just pass an empty string when initially building the query.

Caching the query object is good practice for queries that run frequently.

Limit, Offset, and Pagination

Sometimes you only need a subset of a query, for example the first 10 elements to display in your user interface. This is especially helpful (and resourceful) when you have a high number of entities and you cannot limit the result using query conditions only. The built Query<T> has a .find(long offset, long limit) method with offset and limit arguments:

offset: The first offset results are skipped.

limit: At most limit results of this query are returned.

Lazy loading results

To avoid loading query results right away, Query offers findLazy() and findLazyCached() which return a LazyList of the query results.

LazyList is a thread-safe, unmodifiable list that reads entities lazily only once they are accessed. Depending on the find method called, the lazy list will be cached or not. Cached lazy lists store the previously accessed objects to avoid loading entities more than once. Some features of the list are limited to cached lists (e.g. features that require the entire list). See the LazyList class documentation for more details.


Sometimes you do not want to return objects from a query, but get an aggregated value of a property. ObjectBox supports the following methods (each taking a property as parameter):

  • min / minDouble: Finds the minimum value for the given property over all objects matching the query.
  • max / maxDouble: Finds the maximum value.
  • sum / sumDouble : Calculates the sum of all values. Note: the non-double version detects overflows and throws an exception in that case.
  • avg : Calculates the average (always a double) of all values.

In addition, instead of getting the results themselves, you can get the number of results by calling count().

Removing Objects

To remove all objects matching a query, call query.remove() .

Spread the love
Sign up for fresh ObjectBOX news here. No spam, just fresh developer news once in a while.