androidandroid-roomdatabase-relations

Best way to handle this relation in Room Database


I have three tables and I have a many to many relationship here:

Contact table:

@Entity(tableName = "T_Contacts")
class Contact(
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "_id") var id: Long,
@ColumnInfo(name = "phoneNumber")
var phoneNumber: String = "",

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

@ColumnInfo(name = "active")
var active: Int = 1

@ColumnInfo(name = "contactId")
var contactId: Long = -1

@ColumnInfo(name = "phoneContactId")
var phoneContactId: String = ""

}

Email table:

@Entity(tableName = "T_EmailAddress")
class EmailAddress(
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "_id")
var id : Long,
@ColumnInfo(name="emailAddress")
var emailAddress: String,
@ColumnInfo(name="active")
var active : Int) {

}

And the associative table:

@Entity(tableName = "T_EmailAddressContact",
foreignKeys = [ForeignKey(
    entity = Contact::class,
    parentColumns = arrayOf("contactId"),
    childColumns = arrayOf("contactId"),
    onDelete=ForeignKey.CASCADE),
    ForeignKey(
        entity = EmailAddress::class,
        parentColumns = arrayOf("emailId"),
        childColumns = arrayOf("emailId"),
        onDelete=ForeignKey.CASCADE)]
  )
class EmailAddressContactCrossRef(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "_id")
var id: Long,
@ColumnInfo(name="contactId")
var contactId: Long,
@ColumnInfo(name="emailId")
var emailId : Long,
@ColumnInfo(name="active")
var active : Int ) {

How can I get a list of all the email contacts using relations? I tried:

data class EmailAddressContact(
@Embedded val contact: EmailAddress,
@Relation(parentColumn = "contactId",
    entityColumn = "contactId",
    associateBy = Junction(EmailAddressContactCrossRef::class)
)

val listContacts: List<Contact>
)

but this only gets me a list of all contacts for a certain email address. I want something like this:

data class EmailAddressContact { 
    val id: Long,
    val emailAddress: EmailAddress,
    val contact: Contact,
    val active: Boolean

}

by calling a query:

@Transaction
@Query("SELECT * FROM T_EmailAddressContact")
fun getAllEmailAddressAndContacts(): List<EmailAddressContact>

Solution

  • According to your EmailAddressContact structure it seems you don't need to use junction, just relations. Try this way:

    data class EmailAddressContact(
        @Embedded val emailAddressContactCrossRef: EmailAddressContactCrossRef, // <- there you'll get "id" and "active" fields
        @Relation(
             parentColumn = "contactId",
             entityColumn = "contactId"
        )
        val contact: Contact,
        @Relation(
             parentColumn = "emailId",
             entityColumn = "_id"
        )
        val emailAddress: EmailAddress
    )
    

    and query you mentioned in your question should fit