I am trying to understand how to use Room with relational tables. I have created a Job model, that has a list of locations and therefore needs a 1-to-many relation between the Job and Location object. For that, I have created a JobWrapper data class to hold both the Job and the locations. But, when building I get the following error:
The class must be either @Entity or @DatabaseView. - java.util.Collectionerror: 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). - java.util.Collection \models\JobWrapper.java:12: error: Cannot find the child entity column
parentId
in java.util.Collection. Options: private java.util.Collection<models.Location> locations; public final class JobWrapper { ^ Tried the following constructors but they failed to match:
JobWrapper(models.Job,java.util.Collection<models.Location>) -> [param:job -> matched field:job, param:locations -> matched field:unmatched] models\JobWrapper.java:9: error: Cannot find setter for field.
I notice that it at least cannot find the locations table. But, I do not know how to handle the problem. The problem did not appear while reading from the database - it first appeared when I was trying to put data into the database with my JobDAO. I have already spent a day trying to solve it and are therefore searching for a solution or some advise on how to solve it.
Note: I have been following the following guides:
- https://developer.android.com/training/data-storage/room/relationships#one-to-many
- https://dev.to/normanaspx/android-room-how-works-one-to-many-relationship-example-5ad0
Here follows some relevant code snippets from my projects:
JobWrapper.kt
data class JobWrapper(
@Embedded val job: Job,
@Relation(
parentColumn = "jobid",
entityColumn = "parentId"
) var locations : Collection<Location>
)
Job
@Entity
data class Job (
@PrimaryKey
@NonNull
var jobid : String,
@NonNull
@ColumnInfo(name = "job_status")
var status : JobStatus,
@NonNull
@SerializedName("createdByAuth0Id")
var creator : String,
@SerializedName("note")
var note : String?,
@NonNull
var organisationId : String,
@NonNull
var type : JobType,
@SerializedName("atCustomerId")
@NonNull
@ColumnInfo(name = "working_at_customer_id")
var workingAtCustomerId : String,
@SerializedName("toCustomerId")
@NonNull
@ColumnInfo(name = "working_to_customer_id")
var workingToCustomerId : String,
)
JobStatus.kt
enum class JobStatus {
CREATED,
READY,
IN_PROGRESS,
FINISHED
}
Location.kt
@Entity
data class Location (
@PrimaryKey(autoGenerate = true)
var entityId: Long,
@NonNull
var parentId: String,
@NonNull
var locationId: String,
@NonNull
var type: String
) {
constructor() : this(0, "", "", "")
}
JobDao.kt
@Dao
interface JobDAO {
@Transaction
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(job: JobWrapper)
@Transaction
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(jobs: List<JobWrapper>)
@Transaction
@Update
fun update(job: JobWrapper)
@Transaction
@Delete
fun delete(job: JobWrapper)
@Transaction
@Query("DELETE FROM Job")
fun deleteAll()
@Transaction
@Query("SELECT * FROM Job")
fun getAll(): LiveData<List<JobWrapper>>
}