Room cannot verify the data integrity

Viewed 99296

I am getting this error while running program with Room Database

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.

It seems we need to update Database version, but from where we can do that in Room?

20 Answers

android:allowBackup="true" inside AndroidManifest.xml prevents the data from being cleared even after the app is uninstalled.

Add this to your manifest:

android:allowBackup="false"

and reinstall the app.

Note: Make sure you change it back to true later on if you want auto backups.

Another solution:

Check the identityHash of your old json file and the new json file in apps\schema folder.

If the identityHash is different, it will give that error. Find out what you have changed by comparing both json files if you don't want to change anything.

Make sure you have exportSchema = true.

@Database(entities = {MyEntity.class, ...}, version = 2, exportSchema = true)

json schema file:

  "formatVersion": 1,
  "database": {
    "version": 2,
    "identityHash": "53cc5ef34d2ebd33c8518d79d27ed012",
    "entities": [
      {

code:

private void checkIdentity(SupportSQLiteDatabase db) {
    String identityHash = null;
    if (hasRoomMasterTable(db)) {
        Cursor cursor = db.query(new SimpleSQLiteQuery(RoomMasterTable.READ_QUERY));
        //noinspection TryFinallyCanBeTryWithResources
        try {
            if (cursor.moveToFirst()) {
                identityHash = cursor.getString(0);
            }
        } finally {
            cursor.close();
        }
    }
    if (!mIdentityHash.equals(identityHash) && !mLegacyHash.equals(identityHash)) {
        throw new 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.");
    }
}

By default Android manifest have android:allowBackup="true", Which allow apps to persist their SQLite DB on reinstallation.

Suppose your DATABASE_VERSION was initially 3 and then you decide to reduce DB version from 3 to 1.

@Database(entities = {CallRecording.class}, version = DATABASE_VERSION)
public abstract class AppDatabase extends RoomDatabase {
    public abstract RecordingDAO recordingDAO();

//    static final Migration MIGRATION_1_2 = new Migration(1, 2) {
//        @Override
//        public void migrate(SupportSQLiteDatabase database) {
//            // Since we didn't alter the table, there's nothing else to do here.
//        }
//    };
}

You can achieve it like this

  • Clear App data from Setting. This will remove older DB(DATABASE_VERSION =3)from phone
  • Uninstall your App
  • Reduce DATABASE_VERSION version to 1
  • Build and Reinstall Your App

Its a good practise to keep DATABASE_VERSION as constant.

Do not use this solution in production code!
Use Aniruddh Parihar's answer, or peterzinho16's answer instead!

On android phone:

Uninstall the app or Clear app data

To delete app data: Go settings -> Apps -> Select your app -> Storage -> Clear data

The uninstall (and re-install) not works in every case, so try clear data first!

In order to fix the problem in kotlin:

First

@Database(entities = [Contact::class], version = 2)

Second

val MIGRATION_1_2 = object : Migration(1, 2) {
        override fun migrate(database: SupportSQLiteDatabase) {
            database.execSQL("ALTER TABLE Contact ADD COLUMN seller_id TEXT NOT NULL DEFAULT ''")
        }
    }

Third

private fun buildDatabase(context: Context) = Room.databaseBuilder(
            context.applicationContext,
            EpayDatabase::class.java,
            "epay"
        )
            .addMigrations(MIGRATION_1_2)
            .build()

For more details, check the official documentation

1:- It seems we need to update database version (increment by 1)

enter image description here

2nd Uninstall the app or Clear app data

In my case android:allowBackup="false" making it from true to false worked, as this has given me nightmares before as well, this is the weirdest thing why is this setting enabled by default!

This issue occurs mostly in development.

If you change your schema i.e., rename/add/modify your class containing table entity the integrity between exiting db in your previous build conflicts with new build.

clear the app data or install new build after uninstalling the previous build.

Now, The old db won't conflict with the newer one.

In my case I had an AppDatabase class.

@Database(entities = {GenreData.class, MoodData.class, SongInfo.class,
    AlbumsInfo.class, UserFolderListsData.class, UserPlaylistResponse.PlayLists.class, InternetConnectionModel.class}, version = 3, exportSchema = false)

I updated this version number and it solved the problem. Problem arose because i had added a property in SongInfo class and forgot to update the version number.

Hope it helps someone.

@Database(entities = {Tablename1.class, Tablename2.class}, version = 3, exportSchema = false)

Change the version number in your RoomDatabase class. Increment the version number.

If increasing schema version didn't work with you, provide migration of your database. To do it you need to declare migration in database builder:

Room.databaseBuilder(context, RepoDatabase.class, DB_NAME)
  .addMigrations(FROM_1_TO_2)
.build();

static final Migration FROM_1_TO_2 = new Migration(1, 2) {
@Override
public void migrate(final SupportSQLiteDatabase database) {
    database.execSQL("ALTER TABLE Repo 
                     ADD COLUMN createdAt TEXT");
    }
};

I just had a similar issue in an espresso test and the only thing that fixed it was clearing data and also uninstalling the androidx test apks like:

adb uninstall androidx.test.orchestrator
adb uninstall androidx.test.services

In my case I was making an update to a database that I'll be pre-packaging with my app. None of the suggestions here worked. But I finally figured out that I could open the .db file in a database program (I used "DB Browser for SQLite"), and manually change the "User version" from 2 back to 1. After that, it worked perfectly.

I guess any update you make changes this user version, and this is why I kept getting this error.

Fast Solution

Go to AddDatabase Class and increase your db version

import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase

@Database(entities = arrayOf(Product::class, SatisNok::class), version = 6)
abstract class AppDatabase : RoomDatabase() {
    abstract fun productDao(): ProductDao
    abstract fun satisDao(): SatisNokDao
}

Go to Activity or where you call your db

add the method of migration, here I changed the version from 5 to 6

  val MIGRATION_1_2: Migration = object : Migration(5,6) {
            override fun migrate(database: SupportSQLiteDatabase) {
                // Since we didn't alter the table, there's nothing else to do here.
            }
        }

Now add the migration addition to your db builder as .addMigrations(MIGRATION_1_2)

 val db = Room.databaseBuilder(
                applicationContext,
                AppDatabase::class.java, "supervisor"
            ).fallbackToDestructiveMigration()
                .allowMainThreadQueries()
                .addMigrations(MIGRATION_1_2)
                .build()

For more details you may wish to look at here its getting more complicated day by day where they should provide easier solitions.

after operation you may comment line the //.addMigrations(MIGRATION_1_2) and keep it for the next time

I got the same error during the training program of Codelabs. Where In one training session I created a project and it ran successfully with all database operations. In the next session, I was working with a different repo, but it was an extension of the previous project, From the first build of the extended app only I had got the error.

Maybe Studio keeps authentication techniques with room database that's missing with the new build.

Related