[SOLVED] Android Room Kotlin: entities with non data classes

Issue

Regarding to classes that can/may be used for entities in room whith Kotlin,

  1. Is it mandatory to use data classes? Or could I use ‘normal classes’, i.e., the ones I use for the ‘bussiness logic’
  2. In case data classes are mandatory: can I add functionality to what they have by default? i.e, can I add functions (for whatever taks they may need) to them?

The documentation doesn’t say anything about limiting entities to data classes (although each and every code snippet use a data class).

Thanks.

Solution

Is it mandatory to use data classes?

No, you can use either including a mix.

  • data classes are a convenience class

can I add functionality to what they have by default?

Yes.

Perhaps consider the following:-

@Entity
class Table1 {
    @PrimaryKey
    var id: Long? = null
    var name: String = ""
    @Ignore
    var notAColumnInTheTable = false

    constructor(){}

    @Ignore
    constructor(name: String) {
        this.id = null
        this.name = name
        this.notAColumnInTheTable = true
    }

    fun getIdAndName(): String {
        return id.toString() + ":" + name
    }
}

and :-

@Entity
data class Table2(
    @PrimaryKey
    var id: Long? = null,
    var name: String,
    @Ignore
    var notAColumnInTheTable: Boolean = false
) {
    constructor(name: String) : this( id = null,name = name, notAColumnInTheTable = true)
    fun getIdAndName(): String {
        return id.toString() + ":" + name
    }
}

basically they are the same.

Using :-

@Dao
abstract class Table1And2Dao {
    @Insert
    abstract fun insert(table1: Table1): Long
    @Insert
    abstract fun insert(table2: Table2): Long
    @Query("SELECT * FROM table1")
    abstract fun getAllFromTable1(): List<Table1>
    @Query("SELECT * FROM table2")
    abstract fun getAllFromTable2(): List<Table2>
}
  • note the use of an abstract class rather than the normally see interface

along with a suitable @Database annotated class, in this case one that has a function that returns an instance of the built database and for convenience/brevity allows running on the main thread.

Then using :-

    var db = AppDatabase.getDatabase(this)
    var dao = db.getTable1AndTable2Dao()

    dao.insert(Table1("TABLE1_1"))
    dao.insert(Table2("TABLE2_1"))
    for(t1: Table1 in dao.getAllFromTable1()) {
        Log.d("DBINFO","Name is ${t1.name} ID is ${t1.id} NotAColumnInTable is ${t1.notAColumnInTheTable} idandname = ${t1.getIdAndName()}")
    }
    for(t2: Table2 in dao.getAllFromTable2()) {
        Log.d("DBINFO","Name is ${t2.name} ID is ${t2.id} NotAColumnInTable is ${t2.notAColumnInTheTable} idandname = ${t2.getIdAndName()}")
    }

Results in the log including:-

D/DBINFO: Name is TABLE1_1 ID is 1 NotAColumnInTable is true idandname = 1:TABLE1_1
D/DBINFO: Name is TABLE2_1 ID is 1 NotAColumnInTable is true idandname = 1:TABLE2_1

Via App Inspection :-

enter image description here

and :-

enter image description here

Answered By – MikeT

Answer Checked By – Clifford M. (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *