我的房间有问题。
我在其余的api上使用Gson转换器进行改造,我想和大家分享pojos。通常它可以工作,但是在某些情况下,我需要忽略某些字段,因为我有对象列表。我尝试使用@Ignore批注,但是使用它时,构建过程因以下错误而失败:
错误:实体和Pojos必须具有可用的公共构造函数。您 可以有一个空的构造函数或参数匹配的构造函数 字段(按名称和类型)。公共最终班服务{
^错误:找不到字段的设置器。 私有最终java.lang.String id = null;
^错误:找不到字段的设置器。 私有最终java.lang.String name = null;
^错误:找不到字段的设置器。 私有最终java.lang.String description = null;
因此,使用此类,一切正常:
@Entity(tableName = "services")
data class Service(
@PrimaryKey val id: String,
val name: String,
val description: String,
val parentId: String?
)
由此失败:
@Entity(tableName = "services")
data class Service(
@PrimaryKey val id: String,
val name: String,
val description: String,
val parentId: String?,
@Ignore val test: String
)
我正在使用此版本的房间:
implementation 'androidx.room:room-runtime:2.1.0-alpha06'
kapt 'androidx.room:room-compiler:2.1.0-alpha06'
我知道可以使用var而不是val并添加辅助构造函数来解决问题,但是我不想这样做,我更喜欢保留字段的不可变状态。
是忽略注释的错误吗?为什么没有它,一切正常? 任何帮助表示赞赏:)
答案 0 :(得分:0)
在第二个示例中,服务将转换为Java类,该类具有一个带有四个参数的构造函数。 Room看到@Ignore批注,并且知道它需要绑定3个字段,因此它需要一个具有3个与这些字段类型匹配的参数的构造函数。因为找不到这样的构造函数(或默认的构造函数),所以它失败了。
尝试使最后一个属性为可选,并在构造函数上使用@JvmOverloads批注:
@Entity(tableName = "services")
data class Service @JvmOverloads constructor(
@PrimaryKey val id: String,
val name: String,
val description: String,
val parentId: String?,
@Ignore val test: String? = null
)
这将使Kotlin编译器生成3参数构造函数,并使Room再次满意。
我正在对其余的api使用Gson转换器进行改造,我想 与房间共享pojos。
您可能应该避免这样做,并使用两组类对API响应和数据库数据进行建模。即使在开始的那一刻,您也需要进行一些“修改”以使所有功能正常运行,如果将来更改API或数据库,则需要在更多位置进行更复杂的更改。
答案 1 :(得分:0)
实际上,您可以使用一个类而不使用@JvmOverloads
技巧来保持不变性。您只需要唯一可见的(对Room而言)构造函数即可匹配表的字段。以您的示例为例,
@Entity(tableName = "services")
data class Service @Ignore constructor(
@PrimaryKey val id: String,
val name: String,
val description: String,
val parentId: String?,
@Ignore val test: String
) {
constructor(id: String, name: String, description: String, parentId: String?) :
this(id, name, description, parentId, /* some default value for test */)
}