I'm creating my first Room SQLite Migration and I can't figure out what I'm supposed to do now, the version number in the old Database is 2 and I'm changing it to 3. I get the following error in the console when I try to compile the 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.
My Database code looks like this:
@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;
}
}
While I was writing the migration code I was getting "Migration didn't properly handle" until I fixed then all, after that I started getting the data integrity error.
Thanks in advance.
For production type: You need to write code for migrating from one DB to another https://developer.android.com/training/data-storage/room/migrating-db-versions
For develop debuging version: Try to uninstall app from your phone. (it will remove old database). And than simply build and run again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With