I am using Room in my app with two entities. The whole implementation is below. The Problem is, the given scheme is fixed, which means I do not change anything regarding DB. When I provide a new version of my app to Users over Google Play Console, I get the following issue in Cryshlytics although I did not change anything for DB, just edited UI or another things, which definetly nothing have to do with DB:
Fatal Exception: java.lang.IllegalStateException: Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number.
at androidx.room.RoomOpenHelper.checkIdentity(RoomOpenHelper.java:154)
at androidx.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:135)
.......
Now I am not sure if I change the version of DB, it would work. What is wrong here?
BTW the DB is called from a Fragment like this
val mainDb: MainRepository by lazy { MainRepository(requireContext()) }
val stateDb: StateRepository by lazy { StateRepository(requireContext()) }
What's wrong here?
AppDatabase:
@Database(entities = [Main::class, State::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract val mainDao: MainDao
abstract val stateDao: StateDao
companion object {
private var INSTANCE: AppDatabase? = null
fun getInstance(context: Context): AppDatabase? =
INSTANCE ?: synchronized(AppDatabase::class) {
INSTANCE = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
MY_DB
).allowMainThreadQueries()
.build()
return INSTANCE
}
}
}
Dao:
@Dao
interface StateDao {
@Query("SELECT * FROM $STATE")
fun getAll(): List<State>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(state: State)
@Update
fun update(state: State)
@Query("DELETE FROM $STATE")
fun drop()
}
@Dao
interface MainDao {
@Query("SELECT * FROM $MAIN")
fun getAll(): List<Main>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(main: Main)
@Update
fun update(main: Main)
@Query("DELETE FROM $MAIN")
fun drop()
}
Main:
@Entity(tableName = MAIN)
data class Main(
@PrimaryKey @ColumnInfo(name = NUMBER) val number: Int,
@ColumnInfo(name = CARD) val car: String? = EMPTY,
@ColumnInfo(name = MODEL) val model: String? = EMPTY
) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readInt(),
parcel.readString(),
parcel.readString()
)
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(number)
parcel.writeString(car)
parcel.writeString(model)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<Main> {
override fun createFromParcel(parcel: Parcel): Main {
return Main(parcel)
}
override fun newArray(size: Int): Array<Main?> {
return arrayOfNulls(size)
}
}
}
State:
@Entity(tableName = STATE)
data class State(
@PrimaryKey @ColumnInfo(name = NUMBER) val number: Int,
@ColumnInfo(name = STATE) val state: String? = EMPTY
) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readInt(),
parcel.readString()
)
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(number)
parcel.writeString(question)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<State> {
override fun createFromParcel(parcel: Parcel): State {
return State(parcel)
}
override fun newArray(size: Int): Array<State?> {
return arrayOfNulls(size)
}
}
}
Repository:
class MainRepository(context: Context) {
private val mainDao = AppDatabase.getInstance(context)?.mainDao
fun getAll(): List<Main>? {
return mainDao?.getAll()
}
fun insert(main: Main) {
AsyncInsert(mainDao).execute(main)
}
fun update(main: Main) {
mainDao?.update(main)
}
fun drop() {
mainDao?.drop()
}
private class AsyncInsert(private val dao: MainDao?) : AsyncTask<Main, Void, Void>() {
override fun doInBackground(vararg p0: Main?): Void? {
p0[0]?.let { dao?.insert(it) }
return null
}
}
}
class StateRepository(context: Context) {
private val stateDao = AppDatabase.getInstance(context)?.stateDao
fun drop() {
stateDao?.drop()
}
fun getAll(): List<State>? {
return stateDao?.getAll()
}
fun insert(state: State) {
AsyncInsert(stateDao).execute(state)
}
fun update(state: State) {
stateDao?.update(state)
}
private class AsyncInsert(private val dao: StateDao?) : AsyncTask<State, Void, Void>() {
override fun doInBackground(vararg p0: State?): Void? {
p0[0]?.let { dao?.insert(it) }
return null
}
}
}