为啥 Room 实体不适用于 Android 中的不可变属性

Posted

技术标签:

【中文标题】为啥 Room 实体不适用于 Android 中的不可变属性【英文标题】:Why Room entities don't work with immutable properties in Android为什么 Room 实体不适用于 Android 中的不可变属性 【发布时间】:2018-04-29 15:36:51 【问题描述】:

我一直在探索Room 数据库对象映射库,我发现了一些奇怪的东西。

正如this 回答所暗示的那样,实体数据模型不能具有不可变的属性。

但我检查了google's persistent example with kotlin,Room 也适用于不可变属性。请检查示例中的this 数据类。

这种行为的原因可能是什么?

如果我们可以创建不可变值(val 属性),这可能是一个很好的功能,因为这会限制程序员在创建对象后更改唯一标识符,例如 id。

【问题讨论】:

我不是专门研究 Room 的专家,但我相信如果您想使用 val,您需要为所有内容提供默认值,因为它可能依赖于默认构造函数或其他东西,除非这最近发生了变化。此外,一旦设置值,您将无法更改它们。 @JanVladimirMostert 感谢您的回复。我确实使用默认值进行了测试,但问题似乎仍然存在 【参考方案1】:

这很奇怪,因为我可以使用 val 为我的所有字段创建我的实体类而不会出现问题

@Entity(tableName = "repo")
data class RepoEntity(
        @PrimaryKey @ColumnInfo(name = "id") @SerializedName("id") val id: Int,
        @ColumnInfo(name = "name") @SerializedName("name") val name: String,
        @ColumnInfo(name = "full_name") @SerializedName("full_name") val fullName: String,
        @Embedded(prefix = "owner") @SerializedName("owner") val owner: RepoOwnerEntity,
        @ColumnInfo(name = "html_url") @SerializedName("html_url") val htmlUrl: String,
        @ColumnInfo(name = "description") @SerializedName("description") val description: String?
)

并且数据仍然正确存储在数据库中。

【讨论】:

你能发布你的 gradle 文件吗?项目级别和模块级别? 你可以在我的 github repo 上查看所有代码 > github.com/RR12/KU-android-Project-Setup 所有与 db 相关的东西都应该在 data 模块上。 这是不可能的,我也有同样的问题【参考方案2】:

我认为问题源于某些不能作为构造函数参数的字段。来自@Relation注解的Javadoc:

注意@Relation注解的字段不能是构造函数参数,它必须是公共的或者有公共的setter。

作为一种解决方法,我有一个私有构造函数参数_myRelationProperty 和一个公共字段:

val myRelationProperty: List<MyThings> get() = _myRelationProperty

【讨论】:

以上是关于为啥 Room 实体不适用于 Android 中的不可变属性的主要内容,如果未能解决你的问题,请参考以下文章

Android Room:使用 Room 插入关系实体

为啥以下查询不适用于双 LIKE 子句?

在 Android 12/API 31 中,地理围栏不适用于 IMMUTABLE 未决意图。为啥?

为啥这个 CSS 不适用于 Android 上的 Chrome,但适用于其他任何地方?

为啥 shadowColor: '...' - 不适用于“react-native-drawer”组件的 Android 上的抽屉样式?

为啥此查询可以在 Android Studio 中的 App Inspection 的 Database Inspector 部分工作,但不能在 Room Query 中工作?