即使我更改版本号

时间:2018-02-06 19:31:53

标签: android sqlite android-room

我正在创建我的第一个房间SQLite迁移,我无法弄清楚我现在应该做什么,旧数据库中的版本号是2,我将其更改为3.我得到以下内容我尝试编译App时控制台出错:

java.lang.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.

我的数据库代码如下所示:

@Database(entities = {Vehicle.class, ShockAbsorver.class, Customer.class, Review.class, BadRatingOption.class}, version = 3)
public abstract class AppDatabase extends RoomDatabase{
private static AppDatabase INSTANCE;

public abstract VehicleDao vehicleDao();
public abstract ShockAbsorverDao absorverDao();
public abstract  CustomerDao customerDao();
public abstract ReviewDao reviewDao();
public abstract  OptionDao optionDao();

static final Migration MIGRATION_2_3 = new Migration(2,3) {
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {

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

        // REMOVE COLUMN 'original' FROM Vehicle
        database.beginTransaction();
        database.execSQL("ALTER TABLE vehicle RENAME TO temp_vehicle;");
        database.execSQL("DROP INDEX vehicleRemoteId");
        database.execSQL("CREATE TABLE vehicle(id TEXT NOT NULL PRIMARY KEY,idSuperk INTEGER,idRemote TEXT,model TEXT,year INTEGER,plate TEXT,km INTEGER, FOREIGN KEY(idRemote) REFERENCES review(vehicleId));");
        database.execSQL("CREATE INDEX vehicleRemoteId ON vehicle(idRemote)");
        database.execSQL("INSERT INTO vehicle (id,idRemote,model,year,plate,km) SELECT id,idRemote,model,year,plate,km FROM temp_vehicle;");
        database.execSQL("DROP TABLE temp_vehicle;");
        database.endTransaction();

        // ADD CLOUMN 'id' INTO ShockAbsorver
        database.execSQL("ALTER TABLE shockAbsorver ADD COLUMN id TEXT");

        // CREATE TABLE BadRatingOption
        database.execSQL("CREATE TABLE options (id TEXT NOT NULL PRIMARY KEY,absorverId TEXT,option INTEGER);");
        database.execSQL("CREATE UNIQUE INDEX id ON options(id)");
        database.execSQL("CREATE INDEX absorverId ON options(absorverId)");

        //POPULATE BadRatingOption WITH OPTIONS FROM ShockAbsorver
        Cursor cursor = database.query("SELECT * FROM shockAbsorver");

        ArrayList<String> reviewIds = new ArrayList<>();
        ArrayList<Integer> indexes = new ArrayList<>();
        ArrayList<Integer> options = new ArrayList<>();

        try {
            while (cursor.moveToNext()) {
                reviewIds.add(cursor.getString(cursor.getColumnIndex("reviewId")));
                indexes.add(cursor.getInt(cursor.getColumnIndex("index")));
                options.add(cursor.getInt(cursor.getColumnIndex("option")));

            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            cursor.close();
        }


        for(int i = 0;i<reviewIds.size();i++){
            String absorverId = UUID.randomUUID().toString();
            String optionId = UUID.randomUUID().toString();
            database.execSQL("UPDATE shockAbsorver SET id='"+absorverId+"' WHERE reviewId = '"+reviewIds.get(i)+"' AND `index` = "+String.valueOf(indexes.get(i))+";");
            database.execSQL("INSERT INTO options (id,absorverId,option) VALUES ('"+optionId+"','"+absorverId+"','"+options.get(i)+"');");
        }

        reviewIds = null;
        indexes = null;
        options = null;


        //REMOVE 'option' FROM ShockAbsorver
        database.beginTransaction();
        database.execSQL("ALTER TABLE shockAbsorver RENAME TO temp_shockAbsorver;");
        database.execSQL("CREATE TABLE shockAbsorver(`index` INTEGER NOT NULL,id TEXT,remoteId TEXT,isGood INTEGER,rating INTEGER,isNew INTEGER NOT NULL,isEdited INTEGER NOT NULL,isOriginal INTEGER,observation TEXT,filename TEXT,vehicle TEXT NOT NULL,reviewId TEXT NOT NULL,remoteReviewId TEXT,PRIMARY KEY(reviewId,`index`), FOREIGN KEY(reviewId) REFERENCES review(id));");
        database.execSQL("INSERT INTO shockAbsorver (`index`,remoteId,isGood,rating,isNew,isEdited,isOriginal,observation,filename,vehicle,reviewId,remoteReviewId) SELECT `index`,remoteId,isGood,rating,isNew,isEdited,isOriginal,observation,filename,vehicle,reviewId,remoteReviewId FROM temp_shockAbsorver;");
        database.execSQL("DROP TABLE temp_shockAbsorver;");
        database.endTransaction();


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

    }
};

public static AppDatabase getAppDatabase(Context context){
    if(INSTANCE == null){
        INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                AppDatabase.class,
                "shock-absorver-database")
                .allowMainThreadQueries()
                .addMigrations(MIGRATION_2_3)
                .build();
    }
    return INSTANCE;
}

public static void destroyInstance(){
    INSTANCE = null;
}
}

当我编写迁移代码时,我得到“迁移没有正确处理”,直到我修复了所有,之后我开始收到数据完整性错误。

提前致谢。

3 个答案:

答案 0 :(得分:3)

尝试从手机中卸载应用。 (它将删除旧数据库)。

而不仅仅是构建并再次运行。

答案 1 :(得分:0)

@Database(entities = {Vehicle.class, ShockAbsorver.class, Customer.class, Review.class, 
BadRatingOption.class}, version = 3)

另一个变体(上面的答案也可以)-只需将版本从3增加到4

答案 2 :(得分:0)

您需要致电database.setTransactionSuccessful()

这是交易的标准习惯用法

   db.beginTransaction();
   try {
     ...
     db.setTransactionSuccessful();
   } finally {
     db.endTransaction();
   }