You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Room数据库迁移报错:添加deleted列后约束预期与实际不符

解决Room实体嵌套后的迁移报错问题

嘿,我来帮你排查这个问题!你遇到的这个「预期deleted列notNull为false,实际为true」的错误,核心原因是Room根据实体类生成的预期数据库结构,和你手动执行SQL后的实际结构不匹配。咱们一步步来解决:

1. 先检查实体类的定义是否正确

首先要确保你的PackageModel实体里的deleted字段,和你期望的数据库约束完全一致:

@Entity(tableName = "PackageModel")
data class PackageModel(
    // 其他原有字段...
    @ColumnInfo(
        name = "deleted",
        nullable = false, // 明确标记非空
        defaultValue = "0" // 设置默认值
    )
    val deleted: Int = 0 // 用非空类型Int,而不是Int?
)

因为DeliveryJsonModel通过@Embedded嵌入了PackageModel,Room会自动把PackageModel的字段映射到DeliveryJsonModel对应的表中。这里要注意:

  • 如果你的@Embedded设置了prefix(比如@Embedded(prefix = "pkg_")),那你迁移语句里的列名应该是pkg_deleted,而不是deleted,别搞混了!
  • 不要在DeliveryJsonModel里手动定义deleted字段,否则会和嵌入的字段冲突。

2. 为什么会出现notNull不匹配的报错?

Room会根据你的实体类代码生成「预期的数据库schema」,然后和实际数据库的结构对比。报错说明:

  • Room从实体类解析出的deleted字段是允许为null的(notNull=false)
  • 但你通过ALTER TABLE语句添加的是非空列(notNull=true)

这时候你要对应调整:

方案A:让实体类和SQL保持一致(推荐)

如果你的业务逻辑要求deleted是非空的,那就按上面的代码修正PackageModel的deleted字段,确保它是非空类型+标注nullable=false。这样Room生成的预期schema里,deleted的notNull就是true,和你SQL里的约束匹配。

方案B:调整SQL匹配实体类(不推荐,除非业务允许)

如果你的实体类里deleted是可空类型(比如Int?),那你需要把迁移语句改成允许null:

ALTER TABLE DeliveryJsonModel ADD COLUMN deleted INTEGER DEFAULT 0

(去掉NOT NULL关键字)

3. 清理构建缓存,确保Room更新schema

有时候Android Studio的构建缓存会导致Room没有正确解析实体类的最新改动,这时候你需要:

  • 点击顶部菜单栏的Build -> Clean Project
  • 然后点击Build -> Rebuild Project
  • 可以去app/src/main/schemas/你的包名/数据库版本号.json文件里,确认DeliveryJsonModel表中的deleted字段的notNull值是否为true(如果你用的是方案A)

做完这些再重新运行迁移,应该就能解决报错了。

内容的提问来源于stack exchange,提问作者The Bat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:16:23