'How to implement inheritance for a Room entity (Android, Kotlin)
I'm new to Room and haven't find any posts related to this. I have two classes: BaseModel and ChildModel. ChildModel is a Room entity class, but BaseModel - isn't. How do I extend BaseModel from ChildModel properly? I tried to do it as in the code bellow...
BaseModel.kt:
@Parcelize
open class BaseModel(
open val id: String,
open var name: String,
open var creator: String,
open var dateOfLastEdit: Timestamp,
open var contributors: List<String>,
open var color: Int,
open var offline: Boolean
) : Parcelable {...}
ChildModel.kt (empty constructor used for firebase):
@Entity
@Parcelize
data class ChildModel(
@PrimaryKey(autoGenerate = false)
override val id: String = "",
override var name: String = "",
override var creator: String = "",
@TypeConverters(DateTypeConverter::class)
override var dateOfLastEdit: Timestamp = currentTime(),
@TypeConverters(ListStringConverter::class)
override var contributors: List<String> = emptyList(),
override var color: Int = NO_COLOR,
override var offline: Boolean = false,
var text: String = "",
var lastEditTextPosition: Int = 0,
var lastEditNamePosition: Int = 0,
var lastUserEdited: String = ""
) : Parcelable, BaseModel(id, name, creator, dateOfLastEdit, contributors, color, offline) {
constructor() : this("", "", "", currentTime(), emptyList(), NO_COLOR, false, "", 0, 0, "")
...
}
... but it gives error: "Field has non-unique column name" for all the fields which are overridden from BaseModel. Btw, when create BaseModel as an interface it builds successfully.
My database class:
@Database(entities = [ChildModel::class], version = 1)
@TypeConverters(DateTypeConverter::class, ListStringConverter::class)
abstract class CustomDatabase : RoomDatabase() {
abstract fun childModelDao(): ChildModelDao
companion object {
var INSTANCE: CustomDatabase? = null
fun getDatabase(context: Context): CustomDatabase? {
if (INSTANCE == null) {
synchronized(CustomDatabase::class) {
INSTANCE = Room.databaseBuilder(
context.applicationContext,
CustomDatabse::class.java,
DATABASE
).build()
}
}
return INSTANCE
}
fun destroyDatabase() {
INSTANCE = null
}
}
}
The error is not about upgrading database version, because I deleted the previous one.
Thanks in advance!
Solution 1:[1]
Ok, it seems that Room somehow creates two columns with same names (for parent class and for child class) I tried adding @Ignore
annotation above every field inside BaseModel class. It fixed the issue, the project builds successfully, but I'm not sure that's the best approach.
Solution 2:[2]
In cases where an entity inherits fields from a parent entity, it's usually easier to use the
ignoredColumns
property of the@Entity
attribute
Source: https://developer.android.com/training/data-storage/room/defining-data
The example in the article shows an @Entity data class
inheriting from an open class
.
Based on @Anastasia Dronina's answer, it sounds like the reason to use the ignoredColumns
property of the @Entity
attribute is because Room will duplicate columns corresponding to all the superclass fields.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | friend.code |