我正在创建我的第一个房间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;
}
}
当我编写迁移代码时,我得到“迁移没有正确处理”,直到我修复了所有,之后我开始收到数据完整性错误。
提前致谢。
答案 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();
}