Database tables may relate to each other using 1:1, 1:N, or N:M relations. If you are new to database relations, it’s a good idea to catch up before we discus ORM specifics. Here are some random links discussing relations in general.

In greenDAO, entities relate using to-one or to-many relations. For example, if you want to model a 1:n relation in greenDAO, you will have a to-one and a to-many relation. However, note that the to-one and a to-many relations are not connected with each other, so you will have to update both.

Modelling To-One Relations

The @ToOne annotation defines a relation to another entity (one entity object). Apply it to the property holding the other entity object.

Internally, greenDAO needs an additional property pointing to the ID of the target entity, which is specified by the joinProperty parameter. If this parameter is absent, then an additional column is automatically created to hold the key.

The getter-methods of to-one relations (in this example getCustomer()) resolve the target entity lazily on their first call. Subsequent calls will return the previously resolved object immediately.

Note that if you change the foreign key 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 foreign key property ( customerId) will be updated as well.

Note: To eagerly load to-one relations use loadDeep() and queryDeep() of the entity DAO class. This will resolve an entity with all to-one relations with a single database query. This is great for performance if you always access the related entities.

Modelling To-Many Relations

@ToMany defines a relation to a set of other entities (multiple entity objects). Apply this to the property representing a List of target entities. The referenced entity must have one or more properties pointing to the entity owning the @ToMany.

There are three possibilities to specify the relation mapping, use one of them only:

  • referencedJoinProperty parameter: specify the name of the “foreign key” property in the target entity pointing to the id of this entity.

  • joinProperties parameter: for more complex relations you can specify a list of @JoinProperty annotations. Each @JoinProperty requires a source property in the original entity and a referenced property in the target entity.

  • @JoinEntity annotation: put this additional annotation on your property if you are doing an N:M (many-to-many) relation involving another join entity/table.

Once run, the plugin will generate a getter to resolve the list of referenced entities. For example in the first two cases:

Resolving and Updating To-Many Relations

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 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 cached list. The next get will then requery the related entities:

Bi-Directional 1:N Relations

Sometimes you want to navigate 1:N relations in both directions. In greenDAO, you have to add a to-one and a to-many relation to achieve this.

The following example shows the complete modelling of the customer and order entities, we used as an example before. This time, we use the customerId property for creating both relations:

Let’s assume we have an order entity. Using both relations, we could get the customer and all orders the customer has ever made:

Example: Modelling Tree Relations

You can model a tree relation by modelling an entity with a to-one and a to-many relation pointing to itself:

The generated entity lets you navigate its parent and children:

More examples

Check out the DaoExample project for a complete example Android app.

Also, the DaoTestEntityAnnotation project comes with several relation tests. Which, in addition with the other example and test projects, may serve as further examples.

Spread the love