I am in the process of creating an Android app and I have been bouncing back and forth between different implementations of my database. And for whatever reason, my app is creating databases that are from my past implementations, not the current one, in my data folder even though I have seemingly deleted all the code from my past implementations. Here is some context on how I've changed my database implementation.
- I first started out creating my database using
SQLiteOpenHelper
but quickly abandoned this implementation when I discovered the Room Persistence Library. - I created a database using Room for 3 entities:
SubTask
,MainTask
, and a junction table/entity to relate those 2 entities. - I realized that creating a junction table was not the best implementation since a
SubTask
can only belong to oneMainTask
. So I scrapped the junction entity and added an attribute toSubTask
to relate withMainTask
. This is my current implementation and I plan to stick to it.
This is the current code I have for my database. I have decided to populate it to see if it would translate:
@Database(entities = {SubTask.class, MainTask.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public static final String DATABASE_NAME = "task_db";
private static AppDatabase instance;
public static synchronized AppDatabase getInstance(final Context context) {
if (instance == null) {
instance = Room.databaseBuilder(
context.getApplicationContext(),
AppDatabase.class,
DATABASE_NAME
).fallbackToDestructiveMigration().addCallback(roomCallback).build();
}
return instance;
}
public abstract SubTaskDao getSubTaskDao();
public abstract MainTaskDao getMainTaskDao();
//TESTING TO POPULATE DATABASE
private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
new PopulateDbAsyncTask(instance).execute();
}
};
private static class PopulateDbAsyncTask extends AsyncTask<Void, Void, Void> {
private MainTaskDao mainTaskDao;
private SubTaskDao subTaskDao;
private PopulateDbAsyncTask(AppDatabase db) {
mainTaskDao = db.getMainTaskDao();
subTaskDao = db.getSubTaskDao();
}
@Override
protected Void doInBackground(Void... voids) {
Calendar date1 = Calendar.getInstance();
date1.set(2019, 2, 10);
mainTaskDao.insertMainTasks(new MainTask("School Assignments", 0xFF0000, date1));
Calendar date2 = Calendar.getInstance();
date2.set(2019, 2, 8);
subTaskDao.insertSubTasks(new SubTask("Read database book", date2, 1));
Calendar date3 = Calendar.getInstance();
date3.set(2019, 2, 6);
subTaskDao.insertSubTasks(new SubTask("Read OS book", date3, 1));
return null;
}
}
}
When I build and open my app for the first time, it crashes and I get the following in the log:
2019-03-05 19:53:36.241 20085-20106/com.myname.divideandconquer E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1
Process: com.myname.divideandconquer, PID: 20085
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.
at android.arch.persistence.room.RoomOpenHelper.checkIdentity(RoomOpenHelper.java:135)
at android.arch.persistence.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:115)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onOpen(FrameworkSQLiteOpenHelper.java:151)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:409)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:298)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:96)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:54)
at android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:233)
at com.johnsorhannus.divideandconquer.room.SubTaskDao_Impl$4.compute(SubTaskDao_Impl.java:159)
at com.johnsorhannus.divideandconquer.room.SubTaskDao_Impl$4.compute(SubTaskDao_Impl.java:145)
at android.arch.lifecycle.ComputableLiveData$2.run(ComputableLiveData.java:100)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
When I look in the Device File Explorer, I see the following for my app:
Image 1. task_db
is the database being created with Room. I opened this database with a third-party app and this file contains tables for 3 entities, not 2, so this appears to be from implementation (2). taskManager
is the database that I created using SQLiteOpenHelper
(implementation 1), and it is populated with data that I had hardcoded into the database. I am baffled as to why this database exists. I have deleted all my code from this implementation. I have even searched my entire project for taskManager
to see if I ever gave a database this name anywhere in my code. Nothing!
When I go into the app settings and clear storage and I run the app again on Android Studio, I get no error in the log and I get the following in my Device File Explorer: Image 2. task_db
is completely empty. No tables at all, so I am not exactly sure whether this is from implementation (2) or (3). This is also surprising because I expected the database to be populated with the values that I hardcoded.
I have no idea why these databases are being created even though I have deleted code from my past two implementations. There no longer contains any trace of code from SQLiteOpenHelper
and I have deleted the Dao and Entity for the junction table. Any clue as to what is going on?