Android Room Many-To-Many Relations:

Nabin Shrestha (Noowenz)
2 min readSep 20, 2019

--

If you want to learn more about the main components from Room you could check this article : Room

source:https://media.giphy.com/media/nxWg8kZjJtMuQ/giphy.gif

Junction In Room

Junction to be used for joining a relationship, if a relation should be used as an associative table (also known as junctions table or join table) then can use this annotation to reference such table. This is useful for fetching many-to-many relations.

For example, if you have three tables like:

1.UserTable

@Entity(tableName = "user_table")
data class UserModel(
@PrimaryKey
@ColumnInfo(name = "user_id")
@SerializedName("user_id")
var id: String,
@ColumnInfo(name = "user_name")
@SerializedName("user_name")
var userName: String,
@ColumnInfo(name = "user_address")
@SerializedName("user_address")
var userAddress: String
)

This is a simple user table which stores user pieces of information with table name user_table.

2.GroupTable

@Entity(tableName = "group_table")
data class GroupModel(
@PrimaryKey
@ColumnInfo(name = "group_id")
var groupId: String,

@ColumnInfo(name = "group_name")
var groupName: String,

@ColumnInfo(name = "group_image")
var groupImage: String? = null
)

This table name group_table stores group information of users.

3.GroupUserTable

@Entity(
tableName = "group_user_table",
primaryKeys = ["user_id", "group_id"],
foreignKeys = [
ForeignKey(
entity = UserModel::class,
parentColumns = ["user_id"],
childColumns = ["user_id"],
onDelete = ForeignKey.NO_ACTION),
ForeignKey(
entity = GroupModel::class,
parentColumns = ["group_id"],
childColumns = ["group_id"],
onDelete = ForeignKey.CASCADE)
]
)
data class GroupUserModel(
@ColumnInfo(name = "group_id", index = true)
val groupId: String,
@ColumnInfo(name = "user_id", index = true)
val userId: String
)

This table is a mediator for both user_table and group_table.

If you want to fetch groups with a list of users associated with the group than you could Junction like.

data class GroupWithUserList(
@Embedded
val groupModel: GroupModel,
@Relation(
parentColumn = "group_id",
entity = UserModel::class,
entityColumn = "user_id",
associateBy = Junction(
value = GroupUserModel::class,
parentColumn = "group_id",
entityColumn = "user_id"
)
)
val userList: List<UserModel>
)
@Query("SELECT * FROM group_table")
abstract fun getAllGroupsWithUsers(): LiveData<List<GroupWithUserList>>

In the above example, the many-to-many relationship between UserTable and GroupTable has an associative table defined by the entry GroupUserModel.

Enjoy! Happy coding and feel free to leave a comment. 🙂

--

--