使用Room Database运行程序时出现此错误
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.
似乎我们需要更新数据库版本,但是从何处可以在Room中完成呢?
Answers:
当您第一次遇到此消息时,您很可能正在使用数据库的未发行版本。在这种情况下,很可能您不应该增加数据库版本。只需清除应用程序数据将使您通过异常。
如果不增加数据库(推荐):
您应该从Android设置中清除应用程序的应用程序数据。您可能也可以卸载以前的应用程序版本,然后安装新版本以通过异常。后一种方法在某些情况下不起作用(例如,启用了允许备份时)
由于清除应用程序数据始终有效,因此我每次都采用这种方法。
如果确实增加数据库版本:
您将需要编写数据库迁移代码来说明对数据库模式的任何更改。有关迁移的信息,请参见此处。
编写数据库迁移代码的替代方法是调用fallbackToDestructiveMigration
Room数据库构建器。这可能不是一个好主意。忘记删除此调用,然后忘记升级数据库将导致数据丢失。
// Using this fallback is almost certainly a bad idea
Database database = Room.databaseBuilder(context, Database.class, DATABASE_NAME)
.fallbackToDestructiveMigration()
.build();
再次,如果先前的数据库模式不是在野外生存,则既不需要增加数据库版本也不可以退回到破坏性迁移。
1.0.0-rc1
Room版本中,对我有用的唯一方法是增加数据库版本。
默认情况下,Android清单具有android:allowBackup="true"
,允许应用程序在重新安装时保留其SQLite DB。
假设您DATABASE_VERSION
最初是3,然后决定将数据库版本从3减少到1。
@Database(entities = {CallRecording.class}, version = DATABASE_VERSION)
public abstract class AppDatabase extends RoomDatabase {
public abstract RecordingDAO recordingDAO();
// static final Migration MIGRATION_1_2 = new Migration(1, 2) {
// @Override
// public void migrate(SupportSQLiteDatabase database) {
// // Since we didn't alter the table, there's nothing else to do here.
// }
// };
}
你可以这样实现
保持DATABASE_VERSION
不变是一个好习惯。
即使卸载了应用程序,AndroidManifest.xml中的android:allowBackup =“ true”仍可防止清除数据。
将此添加到清单中:
android:allowBackup="false"
并重新安装该应用。
注意:如果要自动备份,请确保稍后将其更改为true。
另一个解决方案:
在apps \ schema文件夹中检查旧json文件和新json文件的identityHash。
如果identityHash不同,它将给出该错误。如果您不想更改任何内容,则可以通过比较两个json文件来找出更改的内容。
确保您具有exportSchema = true。
@Database(entities = {MyEntity.class, ...}, version = 2, exportSchema = true)
json模式文件:
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "53cc5ef34d2ebd33c8518d79d27ed012",
"entities": [
{
码:
private void checkIdentity(SupportSQLiteDatabase db) {
String identityHash = null;
if (hasRoomMasterTable(db)) {
Cursor cursor = db.query(new SimpleSQLiteQuery(RoomMasterTable.READ_QUERY));
//noinspection TryFinallyCanBeTryWithResources
try {
if (cursor.moveToFirst()) {
identityHash = cursor.getString(0);
}
} finally {
cursor.close();
}
}
if (!mIdentityHash.equals(identityHash) && !mLegacyHash.equals(identityHash)) {
throw new 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.");
}
}
Aniruddh Parihar的回答给了我一个提示,并解决了。
搜索您已扩展的课程RoomDatabase
。在那里,您将找到类似以下的版本:
@Database(entities = {YourEntity.class}, version = 1)
只需增加版本即可解决问题。
它非常简单,如日志所示
Looks like you've changed schema but forgot to update the Database version number.
You can simply fix this by increasing the version number.
只需转到数据库版本类,并通过将当前版本增加1来升级数据库版本。
It seems we need to update database version
。但是我没有提到那个版本。无论如何,感谢您的提示。
在Android手机上:
卸载应用程序或清除应用程序数据
删除应用程序数据:转到设置->应用程序->选择您的应用程序->存储->清除数据
卸载(并重新安装)在每种情况下均不起作用,因此请先尝试清除数据!
就我而言android:allowBackup="false"
,使它从true变为false是可行的,因为这也使我感到恶梦,这是最奇怪的事情,为什么默认情况下启用此设置!
为了解决Kotlin中的问题:
第一
@Database(entities = [Contact::class], version = 2)
第二
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Contact ADD COLUMN seller_id TEXT NOT NULL DEFAULT ''")
}
}
第三
private fun buildDatabase(context: Context) = Room.databaseBuilder(
context.applicationContext,
EpayDatabase::class.java,
"epay"
)
.addMigrations(MIGRATION_1_2)
.build()
有关更多详细信息,请查看官方文档
此问题主要发生在开发中。
如果更改架构,即重命名/添加/修改包含表实体的类,则先前构建中退出db与新构建之间的完整性会发生冲突。
卸载以前的版本后,清除应用程序数据或安装新版本。
现在,旧数据库将不会与新数据库冲突。
android:allowBackup="true"
并明智地使用了它
就我而言,我有一个AppDatabase类。
@Database(entities = {GenreData.class, MoodData.class, SongInfo.class,
AlbumsInfo.class, UserFolderListsData.class, UserPlaylistResponse.PlayLists.class, InternetConnectionModel.class}, version = 3, exportSchema = false)
我更新了此版本号,它解决了问题。出现问题是因为我在SongInfo类中添加了一个属性,却忘记了更新版本号。
希望它能帮助某人。
如果要将Room版本从旧版本升级到1.0.0-alpha9,请访问以下文章。非常好的文章,适合从旧版本迁移到1.0.0-alpha9版本。
在Room新版本1.0.0-alpha9中,Room添加了对NOT NULL约束的支持。
那将改变Room生成的模式。因为它更改了架构,所以它也更改了数据库的identityHash,Room用来唯一标识每个数据库版本。因此,我们需要迁移
就我而言,我在迁移过程中使用了事务,而Room无法使用迁移帮助器来更新哈希
@get:Rule
val migrationTestHelper: MigrationTestHelper =
MigrationTestHelper(InstrumentationRegistry.getInstrumentation(),
C2GDatabase::class.java.canonicalName,
FrameworkSQLiteOpenHelperFactory())
/* Testing method throws error*/
db = migrationTestHelper.runMigrationsAndValidate(C2GDatabase.DB_NAME,
3,
false,
C2GDatabase.Migration_1_2(),
C2GDatabase.Migration_2_3())
override fun migrate(database: SupportSQLiteDatabase) {
/**
Error
database.beginTransaction()
**/
database.execSQL("PRAGMA foreign_keys=off;")
database.execSQL("ALTER TABLE user RENAME TO user_old;")
database.execSQL("CREATE TABLE user ( id_user INTEGER PRIMARY KEY AUTOINCREMENT, external_id INTEGER NOT NULL;")
database.execSQL("INSERT INTO user ( id_user, external_id ) " +
" SELECT id_user, external_id" +
" FROM user_old;")
database.execSQL("CREATE UNIQUE INDEX idx_unique_user ON user (external_id);")
database.execSQL("PRAGMA foreign_keys=on;")
database.execSQL("DROP TABLE user_old;")
//database.endTransaction()
}
@Database(entities = {Tablename1.class, Tablename2.class}, version = 3, exportSchema = false)
在RoomDatabase类中更改版本号。增加版本号。
如果增加的架构版本对您不起作用,请提供数据库的迁移。为此,您需要在数据库构建器中声明迁移:
Room.databaseBuilder(context, RepoDatabase.class, DB_NAME)
.addMigrations(FROM_1_TO_2)
.build();
static final Migration FROM_1_TO_2 = new Migration(1, 2) {
@Override
public void migrate(final SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE Repo
ADD COLUMN createdAt TEXT");
}
};
我在espresso测试中遇到了类似的问题,解决该问题的唯一方法是清除数据并卸载androidx测试apk,例如:
adb uninstall androidx.test.orchestrator
adb uninstall androidx.test.services
就我而言,我尝试了以上所有方法。似乎没有任何效果,因此对我来说,解决方案是简单地设置android:allowBackup="false"
,安装应用程序然后将其设置为true
希望它对其他人有帮助:)
在Codelabs的培训计划中,我遇到了相同的错误。在一个培训课程中,我创建了一个项目,该项目在所有数据库操作中均成功运行。在下一个会话中,我正在使用另一个仓库,但这是先前项目的扩展,从扩展应用程序的第一版开始,只有我遇到了错误。
也许Studio保留了新版本缺少的会议室数据库的身份验证技术。