Search code examples
androidkotlinandroid-room

Ways to do One-to-many relations in android room


I'm looking for a way to create a one-to-many relationship using room. I've seen several examples with two approaches. I don't fully understand them. I didn't write full DAO yet, so maybe I'm missing something there.

Approach 1 with @Embedded

As in this documentation, the relation is done via @Embedded tag. In this scenario is not needed to set a ForeignKey? How to do a ondelete cascade if needed?

@Entity
data class User(
    @PrimaryKey val userId: Long,
    val name: String,
    val age: Int
)

@Entity
data class Playlist(
    @PrimaryKey val playlistId: Long,
    val userCreatorId: Long,
    val playlistName: String
)

data class UserWithPlaylists(
    @Embedded val user: User,
    @Relation(
          parentColumn = "userId",
          entityColumn = "userCreatorId"
    )
    val playlists: List<Playlist>
)

Does the UserWithPlaylists needs the @Entity tag?

Approach 2 with @ForeignKey

@Entity
data class User(
    @PrimaryKey val userId: Long,
    val name: String,
    val age: Int
)

@Entity(foreignKeys = [ForeignKey(entity = SeriesGroup::class,
    parentColumns = arrayOf("playlistId"),
    childColumns = arrayOf("userCreatorId")])
data class Playlist(
    @PrimaryKey val playlistId: Long,
    val userCreatorId: Long,
    val playlistName: String
)

In this scenario is not needed to create a new Class joining both Entities? Also, I don't understand why ForeignKey, parentColumns and childColumns must be of type array. Shouldn't in this case be parentColumns an array and childColumns a Long (as we have one - to many relation)?


Solution

  • As in this documentation, the relation is done via @Embedded tag. In this scenario is not needed to set a ForeignKey? How to do a ondelete cascade if needed?

    This approach is for retrieving data, to make Room generate queries for you. To do onDelete Cascade etc you need a ForeignKey.

    Does the UserWithPlaylists needs the @Entity tag?

    No

    In this scenario is not needed to create a new Class joining both Entities? Also, I don't understand why ForeignKey, parentColumns and childColumns must be of type array. Shouldn't in this case be parentColumns an array and childColumns a Long (as we have one - to many relation)?

    You need some class for every query result, so if you want to query something from both tables, you will need to create one. There is also many-to-many relations support, so you might need multiple keys.

    Both approaches are usually used, they do not exclude, but complement each other.