programing

Room에서 데이터 무결성을 확인할 수 없습니다.

randomtip 2021. 1. 17. 10:50
반응형

Room에서 데이터 무결성을 확인할 수 없습니다.


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.

데이터베이스 버전을 업데이트해야하는 것 같지만 Room에서 할 수있는 곳은 어디입니까?


이 메시지를 처음 접하면 릴리스되지 않은 버전의 데이터베이스에 대해 작업 할 가능성이 큽니다. 이 경우 데이터베이스 버전을 늘리지 않아야합니다 . 앱 데이터를 지우는 것만으로도 예외를 통과하게됩니다.

데이터베이스를 늘리지 않는 경우 (권장) :

Android 설정에서 애플리케이션의 앱 데이터를 지워야합니다. 또는 이전 앱 버전을 제거한 다음 새 버전을 설치하여 예외를 전달할 수 있습니다. 후자의 접근 방식은 특정 조건 (예 : 백업 허용이 활성화 된 경우)에서 작동하지 않습니다.

응용 프로그램 데이터 지우기는 항상 작동하므로 매번 해당 경로를 사용합니다.

데이터베이스 버전을 증가시키는 경우 :

데이터베이스 스키마의 변경 사항을 설명하기 위해 데이터베이스 마이그레이션 코드를 작성해야합니다. 마이그레이션에 대한 정보는 여기참조 하십시오 .

데이터베이스 마이그레이션 코드를 작성하는 다른 방법 fallbackToDestructiveMigration은 Room 데이터베이스 빌더 를 호출 하는 것입니다. 이것은 아마도 좋은 생각이 아닙니다. 이 호출을 제거하는 것을 잊은 다음 데이터베이스를 업그레이드하는 것을 잊으면 데이터가 손실됩니다.

// Using this fallback is almost certainly a bad idea
Database database = Room.databaseBuilder(context, Database.class, DATABASE_NAME)
        .fallbackToDestructiveMigration()
        .build();

이전 데이터베이스 스키마가 라이브가 아닌 경우 다시, 둘 다 데이터베이스 버전을 증가하거나 파괴 이전에 다시 떨어지는 것은 필요하지 않습니다 야생에서 .


기본적으로 Android 매니페스트에는 android:allowBackup="true", 앱이 재설치시 SQLite DB를 유지할 수 있습니다.

DATABASE_VERSION처음에 3 살이었고 DB 버전을 3에서 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.
//        }
//    };
}

이렇게 할 수 있습니다

  • 설정에서 앱 데이터를 지 웁니다. 전화에서 이전 DB (DATABASE_VERSION = 3)를 제거합니다.
  • 앱 제거
  • DATABASE_VERSION 버전을 1로 줄입니다.
  • 앱 빌드 및 재설치

DATABASE_VERSION일정하게 유지하는 것이 좋습니다 .


로그에 표시된 것처럼 매우 간단합니다.

Looks like you've changed schema but forgot to update the version number. 
You can simply fix this by increasing the version number.

데이터베이스 클래스로 이동하여 현재 버전에서 1을 늘려서 DB 버전을 업그레이드하십시오.


Aniruddh Parihar 의 대답은 나에게 힌트를 주었고 해결되었습니다.

확장 한 클래스를 검색합니다 RoomDatabase. 다음과 같은 버전이 있습니다.

@Database(entities = {YourEntity.class}, version = 1)

버전을 올리면 문제가 해결됩니다.


AndroidManifest.xml 내부의 android : allowBackup = "true"는 앱이 제거 된 후에도 데이터가 지워지지 않도록합니다.

다음을 매니페스트에 추가하십시오.

android:allowBackup="false"

앱을 다시 설치하십시오.

참고 : 자동 백업을 원하면 나중에 다시 true로 변경하십시오.

또 다른 해결책 :

이전 json 파일의 identityHash와 apps \ schema 폴더에서 새 json 파일을 확인하십시오.

identityHash가 다른 경우 해당 오류가 발생합니다. 아무것도 변경하지 않으려면 두 json 파일을 비교하여 변경 한 내용을 찾으십시오.

exportSchema = true인지 확인하십시오.

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

json 스키마 파일 :

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

암호:

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.");
    }
}

이 문제는 대부분 개발 단계에서 발생합니다.

스키마를 변경하는 경우 즉, 테이블 엔티티를 포함하는 클래스의 이름을 변경 / 추가 / 수정하면 이전 빌드에서 종료 된 db 간의 무결성이 새 빌드와 충돌합니다.

앱 데이터를 지우 거나 이전 빌드를 제거한 후 새 빌드를 설치합니다 .

이제 이전 db는 최신 db와 충돌하지 않습니다.


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!


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.


If you are upgrading Room version to 1.0.0-alpha9 from old version then please visit below article. Very Good Article for Migrate from old version to 1.0.0-alpha9 version.

https://medium.com/@manuelvicnt/android-room-upgrading-alpha-versions-needs-a-migration-with-kotlin-or-nonnull-7a2d140f05b9

In Room New Version 1.0.0-alpha9 Room adds support for the NOT NULL constraint.

That is going to change the schema that Room generates. Because it changes the schema, it also changes the identityHash of the DB and that is used by Room to uniquely identify every DB version. Therefore, we need a migration


In My case ContentProvider and room database work together so first remove all callback of ContentProvider all over the application with database class which extends SqlLiteOpenHelper Class


In my case i was using a transaction inside the migration and Room could not update the hash using a Migration Helper

@get:Rule
val migrationTestHelper: MigrationTestHelper =

MigrationTestHelper(InstrumentationRegistry.getInstrumentation(),
                C2GDatabase::class.java.canonicalName,
                FrameworkSQLiteOpenHelperFactory()) 
/* Testing method throws error*/
db = migrationTestHelper.runMigrationsAndValidate(C2GDatabase.DB_NAME,
            3,
            false,
            C2GDatabase.Migration_1_2(),
            C2GDatabase.Migration_2_3())


override fun migrate(database: SupportSQLiteDatabase) {

/** 
    Error
    database.beginTransaction()
**/
database.execSQL("PRAGMA foreign_keys=off;")
database.execSQL("ALTER TABLE user RENAME TO user_old;")
database.execSQL("CREATE TABLE user ( id_user INTEGER PRIMARY KEY AUTOINCREMENT, external_id INTEGER NOT NULL;")
database.execSQL("INSERT INTO user ( id_user, external_id ) " +
                        " SELECT               id_user, external_id" +  
                        " FROM                 user_old;")

database.execSQL("CREATE UNIQUE INDEX idx_unique_user ON user (external_id);")
database.execSQL("PRAGMA foreign_keys=on;")
database.execSQL("DROP TABLE user_old;")
//database.endTransaction() 
}

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!


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 I tried all of the above. Nothing seemed to work so the solution for me was simply setting android:allowBackup="false", install the app then set it back to true

Hope it helps others :)


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

ReferenceURL : https://stackoverflow.com/questions/44197309/room-cannot-verify-the-data-integrity

반응형