简体   繁体   中英

Migration not handled properly in Room

I have one db table class where I did change related to indices. Previously indices was like:

@Entity(indices = {@Index(value = {"jobNumber", "jobId"},
        unique = true)})

But I changed it to

@Entity(indices = {
        @Index(value = "jobNumber", unique = true), @Index(value = "jobId", unique = true)
})

But when I tried migration it's giving me issue like:

caused by: java.lang.IllegalStateException: Migration didn't properly handle Job

I need to go with second format only. I tried to add migration but seems not working. Here is my code:

 public static final Migration MIGRATION_4_5 = new Migration(4, 5) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        migrateJobTableForIndices(database);
    }
};

private static void migrateJobTableForIndices(SupportSQLiteDatabase database) {
    //create new table
    database.execSQL(
            "CREATE TABLE Job_new (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, jobId INTEGER NOT NULL, " +
                    "jobNumber TEXT)");

    database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS index_Job_new_jobNumber_jobId ON Job_new (jobNumber, jobId)");
    // Copy the data
    database.execSQL(
            "INSERT INTO Job_new (id, jobId, jobNumber) " +
                    "SELECT id, jobId, jobNumber " +
                    "FROM Job");
    // Remove the old table
    database.execSQL("DROP TABLE Job");
    // Change the table name to the correct one
    database.execSQL("ALTER TABLE Job_new RENAME TO Job");
}

Is there any way to add migration for updated indices format. Any reference is really appreciated

As Room generates index names. You could export the scheme to see what is happening. By adding the following to your build.gradle:

android {
    ...
    javaCompileOptions {
        annotationProcessorOptions {
            arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
        }
    }

    ...
}

Now for the migration.

Beforehand you have to turn the foreign_keys off:

database.execSQL("PRAGMA foreign_keys=OFF;")

You have to drop the existing index. For example:

database.execSQL("DROP INDEX IF EXISTS `index_Job_jobNumber_jobId`")

Then I would suggest renaming the old table.

ALTER TABLE Job RENAME TO Job_old

Create the new table Job .

Then create the index, which you will find in the exported schema location. In this example, it is in your $projectDir/schemas . From the files there you could see and copy how Room creates the indexes and add the creation of these indexes after the table creation.

Migrate the data.

Drop the old table.

Turn the foreign_keys on:

database.execSQL("PRAGMA foreign_keys=ON;")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM