Self-Referential Relations for Tree Structures

With care, you can use Room for self-referential relations: an entity having a foreign key back to itself. This is most commonly seen in tree structures:

The General/RoomTree sample project demonstrates the first of those examples: a Category entity that has an optional parent Category:

package com.commonsware.android.room.dao;

import android.arch.persistence.room.Entity;
import android.arch.persistence.room.ForeignKey;
import android.arch.persistence.room.Ignore;
import android.arch.persistence.room.Index;
import android.arch.persistence.room.PrimaryKey;
import android.support.annotation.NonNull;
import java.util.UUID;
import static android.arch.persistence.room.ForeignKey.CASCADE;

@Entity(
  tableName="categories",
  foreignKeys=@ForeignKey(
    entity=Category.class,
    parentColumns="id",
    childColumns="parentId",
    onDelete=CASCADE),
  indices=@Index(value="parentId"))
class Category {
  @PrimaryKey
  @NonNull
  public final String id;
  public final String title;
  public final String parentId;

  @Ignore
  Category(String title) {
    this(title, null);
  }

  @Ignore
  public Category(String title, String parentId) {
    this(UUID.randomUUID().toString(), title, parentId);
  }

  public Category(@NonNull String id, String title, String parentId) {
    this.id=id;
    this.title=title;
    this.parentId=parentId;
  }
}

Here, Category has a @ForeignKey that points back to Category as the entity, with a parentId column holding the id of the parent Category. onDelete is set to CASCADE, so that when a parent Category is deleted, its children are deleted as well.

Now we can have DAO methods that work with the Category tree:

  @Query("SELECT * FROM categories")
  List<Category> selectAllCategories();

  @Query("SELECT * FROM categories WHERE parentId IS NULL")
  Category findRootCategory();

  @Query("SELECT * FROM categories WHERE parentId=:parentId")
  List<Category> findChildCategories(String parentId);

  @Insert
  void insert(Category... categories);

  @Delete
  void delete(Category... categories);

Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.