ObjectBox Relations

Objects may reference other objects, e.g. by a simple reference or using a List of multiple objects. In database terms, we call those references relations. A relation has a direction. The object defining the relation we call the source object, and the referenced object we call target object. If there is only one target object, we call the relation to-one, and if there can be multiple target objects, we call it to-many. Relations are lazily initialized: the actual target objects are fetched from the database when they are first accessed. Once the target objects are fetched, they are cached for further accesses.

To-One Relations

You have two ways to define a to-one relation to another object. Either by using the ToOne class or by using the @Relation annotation.

The ToOne class (recommended)

The ToOne class is like a smart proxy to the target object. It gets and caches the target object transparently. To get the actual object, call getTarget() on it. This will do a database call on the first access (lazy loading). This is an look-up by ID, which is very fast in ObjectBox. Sometimes you may only need the ID of the target. Then a call to getTargetId() can be more efficient because it does not touch the database at all.

@Relation (Java-only)

You can use @Relation to let ObjectBox generate the ToOne code and a getter and setter for the target object:

Internally, ObjectBox uses an additional property in the source entity to reference the ID of the target entity. Usually this is property is managed by the ToOne object. However, you can make this property to “materialize” in your source object. Just add a property of type long using the default name: name of the relation property plus an “Id” postfix. You can also use any other name by specifying it using the @Relation annotation:

Note that if you change the ID property (here customerId), the next call to the getter ( getCustomer()) will resolve the entity for the updated ID.

Also, if you set a new entity ( setCustomer()), the ID property ( myCustomerId) will be updated as well.

To-Many Relations

To-Many relations are used for List or  ToMany property types. Currently, this must be the back link of a to-one relation as we saw above. This might require you to set up the to-one relation first. Future versions of ObjectBox will drop this requirement.

Use @Backlink to mark a to-many relation as the back link to a to-one relation (currently always required). If there is exactly one to-one relation in the target entity, ObjectBox automatically selects it. If there are multiple to-one matching the entity type, you need to specify the name of the to-one relation. Example: @Backlink(to = "customerId")

Using the example from above we extend it with a to-many relation “orders” in “Customer”:

To-many relations are resolved lazily on the first request, and then cached in the source entity inside a List object. So subsequent calls to the get method of the relation do not query the database.

Updating Relations

The ToOne and ToMany classes assist you to persist the relation state. They keep track of changes and apply them to the database once you put the entity owning the relation. ObjectBox supports relation update for new (not yet persisted; ID is zero) and existing (persisted before; ID is non-zero) entities.

Updating ToOne

The ToOne class offers the following methods to update the relation:

  • setTarget(entity) makes the given entity (new or existing) the new relation target; pass null  to clear the relation
  • setTargetId(entityId) sets the relation to the given ID of an existing target entity; pass 0 (zero) to clear the relation

Updating ToMany

The ToMany class implements the java.lang.List  interface while adding change tracking for entities. If you add entities to an ToMany object, those are scheduled to be put in the database. Similarily, if you remove entities form the ToMany object, those are also scheduled to be put. Note that removing entities from the List does not actually remove the entity from the database; just the relation is cleared. Do not forget to put the owning entity to apply changes tracked by ToMany objects to the database.

Example: Modelling Tree Relations

You can model a tree relation with two @Relation annotations (a to-one and a to-many relation) pointing to itself:

The generated entity lets you navigate its parent and children:

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