Room cannot verify the data integrity when re open the app

Viewed 984

i'm learn how to use Room from Codelabs and now i have two table

when i'm run from Android Studio is normal

but when i'm close and re open the app i got error

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.

error when re open the app, not on install

i'm try to up version number and i still got the error

here my code

@Database(entities = [Type::class], version = 3)
abstract class TypeRoomDb : RoomDatabase(){

    abstract fun typeDao() : TypeDao

    companion object{
        @Volatile
        private var INSTANCE : TypeRoomDb? = null

        fun getDataBase(
            context: Context,
            scope: CoroutineScope
        ): TypeRoomDb {
            return INSTANCE ?: synchronized(this){
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    TypeRoomDb::class.java,
                    Cons.DB_NAME
                )
                    .fallbackToDestructiveMigration()
                    .addCallback(TypeDbCallBack(scope))
                    .build()
                INSTANCE = instance

                instance
            }
        }

        private class TypeDbCallBack(
            private val scope: CoroutineScope
        ) : RoomDatabase.Callback(){
            override fun onOpen(db: SupportSQLiteDatabase) {
                super.onOpen(db)
                INSTANCE?.let { database ->
                    scope.launch(Dispatchers.IO) {
                        populateDb(
                            database.typeDao()
                        )
                    }
                }
            }
        }

        fun populateDb(typeDao: TypeDao){
            typeDao.deleteAll()
            /*out*/
            typeDao.insert(
                Type(
                    "000",
                    "Makan",
                    0
                )
            )
            typeDao.insert(
                Type(
                    "001",
                    "Transportasi",
                    0
                )
            )
            typeDao.insert(
                Type(
                    "002",
                    "Makanan Ringan",
                    0
                )
            )
            typeDao.insert(
                Type(
                    "003",
                    "Komunikasi",
                    0
                )
            )

            /*in*/
            typeDao.insert(Type(
                "500",
                "Gaji",
                1))
            typeDao.insert(
                Type(
                    "5001",
                    "Hadiah",
                    1
                )
            )
        }

    }
}

my second table

@Database(entities = [LogKeuangan::class], version = 2)
abstract class LogKeuanganRoomDb : RoomDatabase() {
    abstract fun logKeuanganDao(): LogKeuanganDao

    companion object {
        @Volatile
        private var INSTANCE: LogKeuanganRoomDb? = null

        fun getDataBase(
            context: Context,
            scope: CoroutineScope
        ): LogKeuanganRoomDb {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    LogKeuanganRoomDb::class.java,
                    Cons.DB_NAME
                )
                    .fallbackToDestructiveMigration()
                    .build()

                INSTANCE = instance
                instance
            }
        }

    }
}
3 Answers

Everything clearly mentioned in

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.

All you need to is increase version and set exportSchema to false

from

@Database(entities = [Type::class], version = 3)

to

@Database(entities = [Type::class], version = 4, exportSchema = false)

Note

@Database creates another db if you want all tables belongs same db then include them into one db. you should not create new db for each table

If you've changed your schema then you'll need to supply migration classes to update the existing data to match the schema:

https://developer.android.com/training/data-storage/room/migrating-db-versions

//EXAMPLE TAKEN DIRECTLY FROM THE LINK SUPPLIED:

val MIGRATION_1_2 = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, `name` TEXT, " +
                "PRIMARY KEY(`id`))")
    }
}

val MIGRATION_2_3 = object : Migration(2, 3) {
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("ALTER TABLE Book ADD COLUMN pub_year INTEGER")
    }
}

Room.databaseBuilder(applicationContext, MyDb::class.java, "database-name")
        .addMigrations(MIGRATION_1_2, MIGRATION_2_3).build()

You could also uninstall the app manually before reinstalling with the DB changes, and then you won't need to concern yourself with migration until the app is published.

thanks to Jasurbek

i'm deleted my second RoomDatabase class, and add my second table to entities

and it's done

@Database(entities = [Type::class, LogKeuangan::class], version = 3)
abstract class TypeRoomDb : RoomDatabase(){

    abstract fun typeDao() : TypeDao
    abstract fun logKeuanganDao() : LogKeuanganDao
Related