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

The ToOne class is like a smart proxy to the target object. It will manage to get and cache the target object. To get the actual object, just call getTarget() on it. 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.

@Relation

If you want to work without the ToOne proxy, 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 specifing 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 may drop this requirement.

Use @Backlink to mark a to-many relation the back link to a to-one relation (currently always required). You can also specify the name of the to-one relation if there are more than one candidate. Example: @Relation(to = "customer");

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

Note: the following section is outdated! With V0.9.12 does automatic syncs to the DB using the ToMany class. Docs will be updated soon.

Updating to-many relations requires some additional work. Because to-many lists are cached, they are not updated when related entities are added to the database. The following code illustrates the behavior:

So to add new related entities, add them manually to the to-many list of the source entity:

Likewise, you can delete related entities:

When adding, updating or removing many related entities you can use the reset method to clear the list of cached entities. The next get will then requery the related entities:

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