我有一个 Android APP 使用 ObjectBox 作为数据库, 并使用纯 Kotlin 语言开发.
今天我想给数据库的一个 Model 添加一个新字段. 于是我就按照惯例的方法:
装到手机上运行时遇到了 Crash, 错误信息如下:
Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter foo
出现这个问题的原因是:
我使用以下方法修复了这个问题:
首先, 先把这个新增字段设为 nullable 的:
var foo: String? = ""
并 make 一下工程.
之后修复的策略是, 在程序刚运行的时机 (尚未开展数据库操作) 补一个数据库操作:
代码如下:
val data = someBox(applicationContext).query().isNull(Project_.foo).build().find()
data.forEach { p ->
p.foo = ""
someBox(applicationContext).put(p)
}
再次编译运行, 没有报错顺利进入程序, 程序已经将数据库中的老数据都更新了.
之后再把这个 model 新增字段改回 non-nullable 的:
var foo: String = ""
再次编译运行, 由于数据库已经更新了, 因此顺利运行.
在前面的解决方法中, 我先把新增字段 nullable 改成 non-nullable, 修复了之后又改回了 nullable.
我现在有一个问题, 不改回来会有问题吗? 就用 nullable 做字段可以吗?
我又试了一下, 将新增字段为 nullable 而不改回来.
发现这样是可以的, 老的数据由于没有这个字段, 这个字段的值就为 null.
新的数据有了这个字段, 这个字段的值就有值.
看来在 Kotlin 中使用 ObjectBox, model 的字段使用 nullable 更好一些.
修复这个问题我是通过两个步骤编译两次才把问题修复了. 这对于线上的产品是很难的.
首先, 这个问题很难用 Hotpatch 修复:
想来想去, 线上解决方案只能清掉数据库了.
我对这件事情的思考是:
这就是我对今天遇到的这个问题的总结, 希望对大家也能有所帮助.
欢迎通过点赞对我提供支持, 你的支持将是我持续写作的动力.