Reputation: 65
To get a OneToMany relation with Room I create a POJO with @Embedded object and @Relation variable.
data class SubjectView(
@Embedded
var subject: Subject,
@Relation(parentColumn = "idWeb", entityColumn = "subject_id", entity = Topic::class)
var topics: List<Topic>?
)
But while compiling I have this error
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]
Well, that constructor [subject : subject, topics : null] looks like the good one ???
However, if I change my class with no-arg constructor and an all params constructor, it does work.
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
}
}
I would like to know why the first (quicker) version does not compile, as it is not as the documentation shows.
Default args for all variables (as I could have seen on other post) in a constructor (data) class seems not to be mandatory though?
Thanks
Upvotes: 5
Views: 2467
Reputation: 8106
There are several topics how data class generate the constructors.
Since you have a nullable Object inside your constructor, it will generate all possible constructors. That means it generates
constructor(var subject: Subject)
constructor(var subject: Subject, var topics: List<Topic>)
There are two ways to solve that. The first one is to predefine all values like and create another ignored constructor with the desired constructor.
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())
}
Another way is creating a half-filled data class like
data class SubjectView(@Embedded var subject: Subject) {
@Relation var topics: List<Topic> = ArrayList()
}
Take care that the first solution is the proper solution and you need to set @Ignore to any other constructor.
Upvotes: 5