【问题标题】:How does Room verify data integrity? Where are the db versions/hashes stored?Room 如何验证数据完整性?数据库版本/哈希存储在哪里?
【发布时间】:2019-08-18 18:07:19
【问题描述】:

我的目标是使用 Room 的新 createFromAsset api 从应用资产加载预加载的数据库。但是,我注意到如果我的预加载数据库在room_master_table 中没有有机(由 Room 生成)ID 和身份哈希,我会收到“IllegalStateException:Room 无法验证数据完整性”。抛出异常。

我尝试使用 Room 生成的精确 db 文件作为它复制的预加载 db 并且这可以工作,但我不知道为什么。这些数据库版本/id/哈希似乎保存在某个地方,Room 会根据这些版本对其进行验证。但是我已经尝试删除本地数据库并卸载应用程序,但仍然抛出相同的异常。

我想知道 room 如何在 room_master_table 中生成特定的 id 和 hash 以及如何验证它们?

【问题讨论】:

  • 我建议你不要在你的预包数据库中包含room_master_table。第一次打开数据库时,Room 将验证模式并创建主表以及哈希值(如果一切正常)。如果您包含room_master_table,那么看起来好像数据库已经被 Room 打开了,在这种情况下,Room 只会比较哈希而不是进行更合适的模式检查。
  • @DanyBoricua 不正确。无论您是否提供room_master_table 房间都会做同样的事情。它始终调用SELECT identity_hash FROM room_master_table,与您是否提供room_master_table 无关。然后它将返回值(null,如果不存在)与编译后的哈希值进行比较。
  • @musooff,这不是我基于 Room 的 OpenHelper(检查主表)的理解。见:android.googlesource.com/platform/frameworks/support/+/…
  • @DanyBoricua 正如您从源代码中指出的那样。它检查 identity_has 内的 room_master_table 不存在 room_master_table

标签: java android android-room


【解决方案1】:

Room Persistence Library 为每个版本的数据库生成唯一的identity_hash。它存储在room_master_table

每次编译应用程序室时都会生成mIdentityHash,反映您当前的数据库架构。每当您第一次运行应用程序并调用数据库时,Room 会将其与已存储在数据库中的mLegacyHash 进行比较。因此,如果这两个哈希值不同,Room 将抛出 IlligalStateException

所有这些过程都使用 注释处理库 完成,您使用

添加到 build.gradle 文件中
kapt "androidx.room:room-compiler:$room_version"
// annotationProcessing androidx.room:room-compiler:$room_version in case you use Java

您可以查看房间 source code 进行详细验证。看看RoomOpenHelper.java 类,它有checkIdentity() 函数,他们检查identity_hash 并在两个身份哈希不匹配时抛出异常。

如果您正在寻找identity_key 的确切生成方式,请查看SchemaIdentityKey.kt

希望对您有所帮助。

【讨论】:

  • 当你提到mLegacyHash时,那是identity_hash当前在数据库中吗?
  • @Dan 是的。 mLegacyHash 是已经存在的,mItendityHash 是它用新代码生成的
猜你喜欢
  • 2021-08-07
  • 2017-10-27
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多