I have research on web but not able to find any solution for the following issue:
I have an app that uses Room Database. room version = 2.6.1 After some time of not being used, or in unexpected cases, the app throws the following exception:
java.lang.IllegalStateException: Room cannot verify the data integrity. Looks like you've changed schema but fot to update the version number. You can simply fix this by increasing the version number. Expected identity hash: 33163c2d5eee97b7482f9e26308bf995, found: null
The SCHEMA wasn't changed at all.
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
open class RoomOpenHelper(
configuration: DatabaseConfiguration,
delegate: Delegate,
identityHash: String,
legacyHash: String
) : SupportSQLiteOpenHelper.Callback(delegate.version) {
private var configuration: DatabaseConfiguration?
private val delegate: Delegate
private val identityHash: String
..................
..................
..................
..................
override fun onOpen(db: SupportSQLiteDatabase) {
super.onOpen(db)
checkIdentity(db)
delegate.onOpen(db)
// there might be too many configurations etc, just clear it.
configuration = null
}
private fun checkIdentity(db: SupportSQLiteDatabase) {
if (hasRoomMasterTable(db)) {
val identityHash: String? = db.query(
SimpleSQLiteQuery(RoomMasterTable.READ_QUERY)
).useCursor { cursor ->
if (cursor.moveToFirst()) {
cursor.getString(0)
} else {
null
}
}
if (this.identityHash != identityHash && this.legacyHash != identityHash) {
throw IllegalStateException(
"Room cannot verify the data integrity. Looks like" +
" you've changed schema but fot to update the version number. You can" +
" simply fix this by increasing the version number. Expected identity" +
" hash: ${ this.identityHash }, found: $identityHash"
)
}
} else {
// No room_master_table, this might an a pre-populated DB, we must validate to see if
// its suitable for usage.
val result = delegate.onValidateSchema(db)
if (!result.isValid) {
throw IllegalStateException(
"Pre-packaged database has an invalid schema: ${result.expectedFoundMsg}"
)
}
delegate.onPostMigrate(db)
updateIdentity(db)
}
}
private fun updateIdentity(db: SupportSQLiteDatabase) {
createMasterTableIfNotExists(db)
db.execSQL(RoomMasterTable.createInsertQuery(identityHash))
}
private fun createMasterTableIfNotExists(db: SupportSQLiteDatabase) {
db.execSQL(RoomMasterTable.CREATE_QUERY)
}
In the database on the device, the room_master_table exists but is empty. Room tries to compare the identity_hash of the current schema with the identity_hash stored in the database and fails.
On checkIdentity() function, Room check if room_master_table is exist. if true, it compares the identity_hash and if not, it tries to recreate the table with the identity_hash Since in my case the table is exist but is empty, it throws IllegalStateException.
Note that the schema verification is not necessary for me, but I understand that it cannot be skipped
I tried to find how the table is empty with no solution. it happens after the user uses the app and leave it for some time.
My only solution is to catch the exception and remove room_master_table so next time it will recreated properly. I don't like such solution so i would like to know if anyone encountered the same issue or if there is a workaround.
Please check the following case:
I saw in comments that the problem is solved but i use Room latest version.