【问题标题】:Android Room Auto Migration for new column not working新列的Android Room Auto Migration不起作用
【发布时间】:2021-10-25 04:12:21
【问题描述】:

我在 stackoverflow 上搜索了一个类似的问题,但没有找到,针对不同情况的其他可能的解决方案也对我不起作用。我打开这个问题,发现我找不到解决这个问题的方法,也找不到类似的问题。


我尝试使用 Android Room 的自动迁移功能,但始终无法正常工作。

目前的情况如下:

我有一个数据库版本 1

我想在一个表中添加一个新列,这是我想做的唯一修改。此列将保存 String 值,仅此而已。

此新列仅存在于数据库版本 2 中

我已经按照 Android 文档设置了数据库

当我再次运行应用程序(数据库版本 1 填充数据的应用程序)时,应用程序崩溃

控制台中的崩溃错误是这样的:

2021-08-24 21:35:53.941 3081-3141/com.app.test E/AndroidRuntime: FATAL EXCEPTION: pool-18-thread-2
    Process: com.app.test, PID: 3081
    java.lang.IllegalStateException: Migration didn't properly handle: My(com.com.app.test.data.datbase.entity.MyEntity).
     Expected:
    TableInfo{name='My', columns=long list of column definitions}
     Found:
2021-08-24 21:35:53.942 3081-3141/com.app.test E/AndroidRuntime: TableInfo{name='My', columns=long list of column definitions, plus the new one}

我已经使用新版本号 (2) 设置了数据库,并将导出模式设置为 true,并定义了从 1 到 2 的自动迁移。

我还在 app gradle 配置选项中定义了 schemaLocation。

我找不到任何解释为什么这不起作用,这是向现有表添加新列的简单操作。

有谁知道为什么这不起作用,我怎样才能让它工作而无需手动编写迁移?

编辑:仔细检查后,数据库迁移中的 defaultValue 定义似乎存在一些问题。

预期显示列的默认值不为空,这是正确的 defaultValue=''NOT_NOTIFIED''

发现显示为空,这是不正确的 defaultValue='NULL'

该实体的列定义如下

@ColumnInfo(name = "notified", defaultValue = "NOT_NOTIFIED")
public String notified = "NOT_NOTIFIED";

但不知何故,它正在生成默认值为 null 的定义或迁移,而不是我设置的值。

【问题讨论】:

    标签: android android-room database-migration


    【解决方案1】:

    我最近遇到了同样的问题,对我来说,问题是我忘记了我前段时间编写的具有相同版本号的手动迁移。

    这可能不是你的情况,但是为了弄清楚为什么我得到了错误的迁移,我在 RoomOpenHelper.javaonUpgrade 方法设置了一个断点,这导致我忘记了手动迁移。所以试一试,它可能会为您提供有关正在发生的事情的更多信息。

    【讨论】:

      【解决方案2】:

      从实体本身的列定义中删除defaultValue 似乎可以解决问题,但要求该列具有默认值。这似乎不是正确的行为,而是自动迁移逻辑中某处的错误。

      希望有人可能对正在发生的事情有所了解,并提出一个适当的解决方案,而不是删除defaultValue 定义。

      【讨论】:

      • defaultValue 只能在您使用 @Query("INSERT INTO (<csv of column names>) VALUES(<csv list of values that match the columns>) WHERE 列使用默认值 IS NOT 之一时使用要插入的列。使用@Insert 将在列中插入一个空值,因此不应用默认值。根据未出现在列列表中的表列填充默认列值(指定为 CREATE TABLE 语句的一部分),如果未指定默认值,则填充为 NULL。 sqlite.org/lang_insert.html
      • 糟糕,忘记了 INSERT INTO 的表名。应该是@Query("INSERT INTO <the table name> (<csv of column names>) VALUES(<csv list of values that match the columns>)
      • @MikeT 我没有做任何@Query,这实际上是 Android 的完整自动迁移,我没有做任何事情。
      猜你喜欢
      • 2021-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-18
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      相关资源
      最近更新 更多