I am encountering the issue stated in the title. I have the following entities:
@Entity(tableName = "Person")
data class Person(@PrimaryKey var id: Int,
var firstName: String,
var surname: String,
var age: Int,
var numberOfHobbies: Int) {
@Ignore
constructor() : this(0, "", "", 0, 0)
}
@Entity(tableName = "Skill")
data class Skill(@PrimaryKey var id: Int,
var skillName: String) {
@Ignore
constructor() : this(0, "")
}
@Entity(tableName = "PersonSkill")
data class PersonSkill(var personId: Int,
var skillId: Int) {
@Ignore
constructor() : this(0, 0)
@field:PrimaryKey(autoGenerate = true)
var id: Int = 0
}
And the following relationships:
data class SkillWithPersons(
@Embedded var skill: Skill = Skill(0, "UNKNOWN"),
@Relation(
parentColumn = "id",
entityColumn = "skillId",
entity = PersonSkill::class,
projection = arrayOf("personId")
) var personIds: List<Int> = emptyList()
) {
constructor() : this(Skill(0, "UNKNOWN"), emptyList())
}
data class PersonWithSkills(
@Embedded var person: Person = Person(0, "UNKNOWN", "UNKNOWN", 0, 0),
@Relation(
parentColumn = "id",
entityColumn = "personId",
entity = PersonSkill::class,
projection = arrayOf("skillId")
) var skillIds: List<Int> = emptyList()
) {
constructor(): this(Person(0, "UNKNOWN", "UNKNOWN", 0, 0), emptyList())
}
And I have tried everything, and yet it does not work. I keep getting the following error with kotlin-kapt:
e: 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).
e:
e: Tried the following constructors but they failed to match:
e: Integer(int) : [value : null]
e: Integer(java.lang.String) : [s : null]
e: 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).
e:
e: java.lang.IllegalStateException:
I am using the following versions:
Android Studio 3.0 with Gradle 4,
Room: 1.0.0-alpha9-1,
Build tools: 26.0.2,
Kotlin: 1.1.51
It seems there's a bug with the use of @Relation as kotin-kapt seems to no handle it.
Thanks @rs146 for reporting this. The problem here is that Room can't find the right constructor for the elements in the relation, when the element is Int (or Integer in Java). I created an issue on our internal tracker for this but chances are this won't be fixed for the 1.0 release, unfortunately.
For now, the workaround is to return List<PersonSkill> instead of List<Int> for the element annotated with @Relation.
Hi @florina-muntenescu, I tried that but I'm now getting the following error:
/Users/xyz/git-android/android-sample-sdk/app/build/generated/source/kapt/debug/uk/co/xyz/persistence/dao/PeopleDao_Impl.java:209: error: incompatible types: <null> cannot be converted to int
_item_1 = new PersonSkill(null,_tmpSkillId);
^
My PersonWithSkills relation class now has been modified to look like the following:
data class PersonWithSkills(
@Embedded var person: Person = Person(0, "UNKNOWN", "UNKNOWN", 0, 0),
@Relation(
parentColumn = "id",
entityColumn = "personId",
entity = PersonSkill::class,
projection = arrayOf("skillId")
) var skillIds: List<PersonSkill> = emptyList()
)
It seems to break in the generated Dao_Impl. My DAO looks like the following:
@Dao
interface PeopleDao {
@Query("SELECT * FROM Person")
fun findAllPeople(): Flowable<List<Person>>
@Insert
fun savePerson(person: Person)
@Query("SELECT * FROM Person")
fun findAllPeopleWithSkills(): Flowable<List<PersonWithSkills>>
}
"Note that the @Relation annotated field cannot be a constructor parameter, it must be public or have a public setter." - from docs
Room first constructs the object and then sets the data.
Got the same error, fixed by upgrading arch lifecycle version from 1.0.0 to 1.1.1, thanks
Moving the @Ignore and @Relation fields to body class solved the issue for me
Most helpful comment
Thanks @rs146 for reporting this. The problem here is that Room can't find the right constructor for the elements in the relation, when the element is
Int(orIntegerin Java). I created an issue on our internal tracker for this but chances are this won't be fixed for the 1.0 release, unfortunately.For now, the workaround is to return
List<PersonSkill>instead ofList<Int>for the element annotated with@Relation.