会议室:相关实体-可用的公共构造函数

Twe*_*y B 5 android entities kotlin android-room android-architecture-components

为了获得与Room的OneToMany关系,我使用@Embedded对象和@Relation变量创建一个POJO 。

data class SubjectView(
    @Embedded
    var subject: Subject,

    @Relation(parentColumn = "idWeb", entityColumn = "subject_id", entity = Topic::class)
    var topics: List<Topic>?
)
Run Code Online (Sandbox Code Playgroud)

但是在编译时出现此错误

 error: Entities and Pojos must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type)
[...]
Tried the following constructors but they failed to match:
SubjectView(biz.eventually.atpl.data.db.Subject,java.util.List<biz.eventually.atpl.data.db.Topic>) : [subject : subject, topics : null]
Run Code Online (Sandbox Code Playgroud)

好吧,那个构造函数[subject:subject,topic:null]看起来像是一个好的????

但是,如果我使用no-arg构造函数和all params构造函数更改类,则它确实可以工作。

class SubjectView() {
    @Embedded
    var subject: Subject = Subject(-1, -1, "")

    @Relation(parentColumn = "idWeb", entityColumn = "subject_id", entity = Topic::class)
    var topics: List<Topic>? = null

    constructor(subject: Subject, topics: List<Topic>?) : this() {
        this.subject = subject
        this.topics = topics
    }
}
Run Code Online (Sandbox Code Playgroud)

我想知道为什么第一个(快速)版本不能编译,因为它没有如文档所示。

构造函数(数据)类中所有变量的默认参数(如我在其他文章中所见)似乎不是强制性的吗?

谢谢

Ema*_*l S 5

数据类如何生成构造器有几个主题。

由于构造函数内部有一个可为空的Object,它将生成所有可能的构造函数。这意味着它会产生

constructor(var subject: Subject)
constructor(var subject: Subject, var topics: List<Topic>) 
Run Code Online (Sandbox Code Playgroud)

有两种解决方法。第一个是预定义所有类似的值,并使用所需的构造函数创建另一个被忽略的构造函数。

data class SubjectView(
    @Embedded
    var subject: Subject,

    @Relation(parentColumn = "idWeb", entityColumn = "subject_id", entity = Topic::class)
    var topics: List<Topic> = ArrayList()
) {
 @Ignore constructor(var subject: Subject) : this(subject, ArrayList())
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是创建一个半填充数据类,例如

data class SubjectView(@Embedded var subject: Subject) {
    @Relation var topics: List<Topic> = ArrayList()
}
Run Code Online (Sandbox Code Playgroud)

请注意,第一个解决方案是正确的解决方案,您需要将@Ignore设置为任何其他构造函数。