java - 仅向多个表的主键添加 @NonNull 注释的房间迁移
问题描述
我正在将应用程序从目标sdk 25升级到目标sdk 29,我房间数据库中的所有表都有一个@PrimaryKey 注释,但没有用@NonNull 注释。现在我的目标是 sdk 29,房间需要 @NonNull 注释,不幸的是这会导致我的应用程序在启动时崩溃,除非我重新安装。
没有全新安装导致的错误:
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:318)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:
我认为这是因为我的数据库必须迁移,因为它可以在全新安装上运行。
到目前为止,我已经找到了一些有用的堆栈溢出答案,例如这个。
但这需要我重写数据库中的每个表,并确保我也将所有索引都带过来。我不想这样做,因为我确信我会错过一些东西,并且会产生多个错误。
有没有更简单的方法来进行房间迁移,我只需将 @NonNull 注释添加到我的所有主键?
或者,我看到提到从 SQLite 表中获取模式,它将所有索引封装到查询中,但我不知道如何在迁移中获取该模式。
添加 NonNull 标签后的示例类:
@Entity(tableName = "FavoriteTrip"
, indices = { @Index("tripPlanId") }
, foreignKeys = @ForeignKey(entity = TripPlan.class, parentColumns = "id", childColumns = "tripPlanId"))
public class FavoriteTrip {
@PrimaryKey @NonNull
private String id = UUID.randomUUID().toString();
解决方案
有没有更简单的方法来进行房间迁移,我只需将 @NonNull 注释添加到我的所有主键?
我相信有但实际上并没有玩太多(只是快速尝试,发现您仍然需要创建实体以正确匹配表格)。那就是让 ROOM 转换数据库(您可能必须删除room_master_table),也就是使用最近添加的createFrom方法之一。
这些会将数据库转换为房间可以接受的数据库,但据我所知,它不会创建实体,我已经看到由于预期...... . 发现....... 很难阅读。
另一种选择是我一直在使用的东西,它可以转换数据库并另外生成基本的实体/道和数据库代码 (Java)。这个工具可以在RoomExistingSQLiteDBConverter找到,它链接了 github 上的源代码。
- 作为一个非常快速的概述,
:-
您运行应用程序(可能在 AS 模拟器中,但可能在真实设备上)。
将数据库复制到公共外部存储中的任何(bar 1 保留文件夹)文件夹中(在应用程序运行之前或运行时,如果后者则单击刷新按钮)。
- 查看列出的各种组件,了解潜在的突出问题。
- 高兴时单击转换按钮。
- 将准备好导入的数据库(通常作为资产到资产文件夹中)复制到正在开发/更改的应用程序。
- 将代码复制到应用程序中的相应文件夹中。
- 编辑代码以引入适当的导入。
- 编写代码以从 assets 文件夹中复制数据库。
- 测试。
推荐阅读
- ruby-on-rails - 使用 ruby send 方法创建和构建一个新类
- c# - 按二级关联总和排序
- macos - 为什么我不能在 mac 上运行 apt install?
- javascript - ExtJS 数据模型未知数量的字段
- javascript - 我可以为装饰文本添加鼠标点击回调吗?
- ruby-on-rails - 如何使用 Windows 的 bootsnap 修复“无法构建 gem 原生扩展”错误
- android - 如何创建改造响应
并自己设置代码? - gcc - gFortran 和 OpenACC 支持
- python - 如何以可能使用库函数的pythonic方式在python中的两个字符串之间找到最长的公共后缀前缀?
- flutter - 有没有办法为属性 floatingActionButton 返回 2 个值或在变量更改时调用 setState?