web-dev-qa-db-fra.com

Room ne peut pas vérifier l'intégrité des données

Je reçois cette erreur lors de l'exécution du programme avec 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.

Il semble que nous devions mettre à jour la version de la base de données, mais à partir de laquelle pouvons-nous le faire dans Room?

29
Ravi Rupareliya

Lorsque vous rencontrez ce message pour la première fois, vous travaillerez probablement avec une version non publiée de la base de données. Si tel est le cas, vous ne devez probablement pas incrémenter la version de la base de données}. En effaçant simplement les données de l'application, vous déplacerez l'exception.

Si vous n'incrémentez pas la base de données (recommandé):

Vous devez effacer les données d'application de l'application des paramètres Android. Vous pouvez également éventuellement désinstaller la version précédente de l'application, puis installer la nouvelle version pour que l'exception soit transmise. Cette dernière approche ne fonctionne pas dans certaines conditions (par exemple, quand autoriser la sauvegarde est activée)

Comme l'effacement des données d'application fonctionne toujours, je prends cet itinéraire à chaque fois.

Si vous incrémentez la version de la base de données:

Vous devrez écrire le code de migration de la base de données pour prendre en compte toute modification apportée au schéma de base de données. Voir ici pour plus d’informations sur la migration. 

Une alternative à l'écriture du code de migration de base de données consiste à appeler fallbackToDestructiveMigration dans le générateur de base de données de pièce. Ce n'est probablement pas une bonne idée. Si vous oubliez de supprimer cet appel, puis de mettre à niveau la base de données, vous perdrez des données.

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

Là encore, ni incrémenter la version de la base de données ni recourir à une migration destructive n'est nécessaire si le schéma de base de données précédent n'est pas vivant à l'état sauvage.

52
methodsignature

C'est très simple comme le montre le journal 

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

Accédez simplement à votre classe Database et mettez à niveau votre version de base de données en augmentant de 1 la version actuelle 

9
Aniruddh Parihar

Par défaut, les manifestes Android ont `Android: allowBackup =" true ", ce qui permet aux applications de conserver leur base de données SQLite lors de la réinstallation. 

Supposons que votre DATABASE_VERSION était initialement 3 et que vous décidez ensuite de réduire la version de la base de données de 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.
//        }
//    };
}

Vous pouvez y arriver comme ça

  • Effacer les données de l'application du paramètre. Cela supprimera les anciennes bases de données (DATABASE_VERSION = 3) du téléphone.
  • Désinstallez votre application
  • Réduire la version de DATABASE_VERSION à 1
  • Construire et réinstaller votre application 

C'est une bonne pratique de garder DATABASE_VERSION comme constante.

9
Hitesh Sahu

Aniruddh Parihar La réponse de/m'a donné un indice et il a résolu.

Recherchez une classe dans laquelle vous avez étendu RoomDatabase. Vous y trouverez une version comme ci-dessous:

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

il suffit d'augmenter la version et le problème est résolu.

7
Ravi Rupareliya

Ce problème se produit principalement en développement.

Si vous modifiez votre schéma, c'est-à-dire, renommez/ajoutez/modifiez votre classe contenant l'entité de table, l'intégrité entre la base de données existante dans votre construction précédente est en conflit avec la nouvelle construction.

efface les données de l'application ou installez la nouvelle version après avoir désinstallé la version précédente

Maintenant, l'ancienne base de données n'entrera pas en conflit avec la plus récente.

3
sudesh

Dans mon cas, j'avais une classe AppDatabase. 

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

J'ai mis à jour ce numéro de version et cela a résolu le problème. Un problème est survenu parce que j'avais ajouté une propriété dans la classe SongInfo et que j'avais oublié de mettre à jour le numéro de version. 

J'espère que ça aide quelqu'un.

2
Harry .Naeem

Dans mon cas, j'utilisais une transaction dans la migration et Room ne pouvait pas mettre à jour le hachage à l'aide d'un assistant de migration.

@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() 
}
2
JARP

Dans mon cas, ContentProvider et la base de données de pièce fonctionnent ensemble; supprimez donc tout rappel de ContentProvider dans toute l'application avec la classe de base de données qui étend la classe SqlLiteOpenHelper

2
chaman

Si vous mettez à niveau la version de Room vers la version 1.0.0-alpha9 à partir de l'ancienne version, consultez l'article ci-dessous. Très bon article pour migrer de l'ancienne version à la version 1.0.0-alpha9.

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

In Room Nouvelle version 1.0.0-alpha9 Room ajoute la prise en charge de la contrainte NOT NULL.

Cela va changer le schéma généré par Room. Dans la mesure où il modifie le schéma, il modifie également le identityHash de la base de données, qui est utilisé par Room pour identifier de manière unique chaque version de la base de données. Par conséquent, nous avons besoin d'une migration

1
Bhargav Pandya

Vérifiez le identityHash de votre ancien fichier JSON et le nouveau fichier Json dans le dossier apps\schema.

Si identityHash est différent, l'erreur sera générée. Découvrez ce que vous avez changé en comparant les deux fichiers JSON si vous ne voulez rien changer.

Assurez-vous d'avoir exportSchema = true.

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

fichier de schéma json:

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