java.lang.IllegalStateException: Room cannot verify the data integrity.

This is a very easy error to fix and usually is caused when you change a Room entity configuration. For testing purposes, just increment your version number in your abstract RoomDataBase() class & add a call to “.fallbackToDestructiveMigration()” just before “.build()” on your Room.databaseBuilder() call.

NOTE, THAT THIS MAY DESTROY ALL SAVED DATA AND SHOULD BE REMOVED BEFORE RELEASING TO PRODUCTION.

I’ll include my abstract call and with the changes in bold for clarity:

@Database(
    entities = [ Ingredient::class, Meal::class, MealPlan::class, Recipe::class],
    version = 1,
    exportSchema = false
)
@TypeConverters(Converters::class)
abstract class MealPlannerDatabase : RoomDatabase() {


    abstract fun mealPlannerDao(): MealPlannerDao

    companion object {

        //@Volatile tells the JVM to make assignments to the instance variable visible to all threads. This is needed
        // when coroutines are used as they are processed on different threads.
        @Volatile
        private var instance: MealPlannerDatabase? = null

        fun getDatabase(
            context: Context,
            scope: CoroutineScope
        ) : MealPlannerDatabase =

            this.instance ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context,
                    MealPlannerDatabase::class.java,
                    "MealPlanner2"
                )
                    .addCallback(MealPlannerDatabaseDatabaseCallback(scope))
.fallbackToDestructiveMigration()
                    .build()

                this.instance = instance

                instance


            }


    }

    private class MealPlannerDatabaseDatabaseCallback(
        private val scope: CoroutineScope
    ) : RoomDatabase.Callback() {

        override fun onCreate(db: SupportSQLiteDatabase) {
            super.onCreate(db)
            instance?.let { database ->
                scope.launch {
                    populateDatabase(database.mealPlannerDao())
                }
            }
        }

        suspend fun populateDatabase(mealPlannerDao: MealPlannerDao){
            // initialize if needed
        }
    }
}

That’s it unless your project is a production app, and your need to implement a migration strategy. If so, you should look here.

Leave a Reply

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