我正在创建一个Android应用,并且在数据库的不同实现之间来回弹跳。无论出于何种原因,即使我似乎删除了过去实现中的所有代码,我的应用仍在我的数据文件夹中创建来自过去实现的数据库,而不是当前数据库。这是一些有关如何更改数据库实现的上下文。
SQLiteOpenHelper
创建数据库,但是当我发现Room Persistence Library时很快放弃了该实现。SubTask
,MainTask
,以及用于关联这两个实体的联结表/实体。SubTask
只能属于一个MainTask
。因此,我报废了联结实体,并向SubTask
添加了一个与MainTask
相关的属性。这是我目前的实现方式,我打算坚持下去。这是我数据库的当前代码。我决定填充它,看看它是否可以翻译:
@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;
}
}
}
当我第一次构建并打开我的应用程序时,它崩溃了,并且我在日志中得到以下内容:
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)
当我在设备文件资源管理器中查看时,我的应用程序会看到以下内容:
Image 1。 task_db
是使用Room创建的数据库。我使用第三方应用程序打开了该数据库,该文件包含3个实体(而不是2个)的表,因此这似乎来自实现(2)。 taskManager
是我使用SQLiteOpenHelper
创建的数据库(实现1),其中填充有我已硬编码到数据库中的数据。我对为什么这个数据库存在感到困惑。我已经从该实现中删除了所有代码。我什至在整个项目中搜索了taskManager
,以查看是否在代码中的任何地方给数据库指定了这个名称。没事!
当我进入应用程序设置并清除存储,然后再次在Android Studio上运行该应用程序时,日志中没有错误,并且在我的设备文件资源管理器中得到了以下内容:Image 2。 task_db
完全为空。根本没有表,所以我不确定这是来自实现(2)还是(3)。这也是令人惊讶的,因为我希望数据库中将填充我硬编码的值。
即使我从过去的两个实现中删除了代码,我也不知道为什么要创建这些数据库。这里不再包含来自SQLiteOpenHelper
的任何代码痕迹,并且我删除了联结表的Dao和Entity。有什么线索吗?
答案 0 :(得分:0)
查看错误。它向您显示了错误原因。
java.lang.IllegalStateException:Room无法验证数据完整性。看起来您已更改架构,但忘记更新版本号。您只需增加版本号即可解决此问题。
因此,您已在代码中更改了某些架构。因此,只需将数据库版本从1更改为2。
Database(entities = {SubTask.class, MainTask.class}, version = 2)
答案 1 :(得分:0)
您必须卸载应用程序(或从内部存储中删除文件),否则先前版本的Room
模式将持久存在(就像使用{{ 1}}),然后将新架构与旧架构进行比较。打算创建迁移时,增加版本号仅对已经发布的应用有意义。