How to query a complex nested objects in Room?

Rooms works with entity/table and it does not allow to manage structured object like you needed. The only thing you can do is execute queries separately and then build your ResultObject.


You can nest classes defining relationships as much as you want.

class DeepDialog {
    @Embedded lateinit var embedded: Dialog

    @Relation(parentColumn = "id", entityColumn = "dialogId", entity = Message::class)
    lateinit var messages: List<DeepMessage>
}

class DeepMessage {
    @Embedded lateinit var embedded: Message    

    @Relation(parentColumn = "id", entityColumn = "messageId", entity = ImageContent::class)
    lateinit var imageContents: List<DeepImageContent>
}

... etc

I think Room guys should come with something more elegant as this solution has at least two issues.

  1. It introduces quite annoying boilerplate.
  2. @Relation annotation can be used only on Lists or Sets so it doesn't cover scenarios where you have 1:1 relationship.

Imagine your Dialog would have only one Message by definition (instead of many). In that case, you wouldn't want your DeepDialog to have messages: List<> accessor but message: Message instead. The only way around I found is:

class DeepDialog {
    @Embedded lateinit var embedded: Dialog

    @Relation(parentColumn = "id", entityColumn = "dialogId", entity = Message::class)
    internal lateinit var messages: List<DeepMessage>
    val message get() = messages.firstOrNull()
}