我试图了解如何使用房间与关系表.我已经创建了一个作业模型,它有一个位置列表,因此需要一个1到多的作业和位置对象之间的关系.为此,我已经创建了一个JobWrapper数据类来容纳作业和位置.但是,当构建我得到以下错误:
类必须是@Entity或@DatabaseView. - java.util.Collectionerror:实体和POJO必须有一个可用的公共构造函数。您可以有一个空的构造函数,也可以有一个参数与字段匹配的构造函数(按名称和类型)。- java.util.Collection \models\JobWrapper.java:12:错误:在java. util. Collection中找不到子实体列parentId
。选项:private java.util.Collection<models.Location>locations; public final class JobWrapper { ^尝试了以下构造函数,但它们无法匹配:
JobWrapper(models.Job,java.util.Collection<models.Location>)-〉[param:job -〉matched field:job,param:locations -〉matched field:unmatched] models\JobWrapper.java:9:错误:找不到字段的setter。
我注意到它至少找不到locations表。但是,我不知道如何处理这个问题。这个问题在从数据库阅读时没有出现-它第一次出现是在我试图用JobDAO将数据放入数据库时。我已经花了一天的时间试图解决它,因此正在寻找解决方案或如何解决它的一些建议。
- 注意:我一直遵循以下指南:*
- 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
下面是我的项目中的一些相关代码片段:
JobWrapper.kt
data class JobWrapper(
@Embedded val job: Job,
@Relation(
parentColumn = "jobid",
entityColumn = "parentId"
) var locations : Collection<Location>
)
职位
@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
}
位置.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>>
}
2条答案
按热度按时间oewdyzsn1#
正如Kraigolas指出的,您只能直接使用JobWrapper来提取需要通过实际底层实体插入/删除/更新的数据。
请考虑以下内容
[***] JobDao**
我已经测试过了,使用的演示/示例如下(显然JobDao是如上所述)
所使用的POJO和实体为:
JobWrapper
*列表代替收藏
职位
位置
@使用的数据库JobDatabase
测试/演示活动MainActivity
这是:
1.获取DB示例和dao。
1.通过单个JobWrapper添加作业及其位置
1.通过由
createJobWrapperList
函数生成的作业 Package 列表添加x(10)个作业和每个作业的3个位置。4.删除通过getJobWrapperByJobId
获得的作业 Package ,包括使用与作业ID“job 6”相关联的作业 Package 的delete
删除底层位置(true
)。1.获取与“job 7”关联的JobWrapper,更改创建者并将类型为“M”的位置更改为“UPDATED”(仅一个),然后使用
update(JobWrapper)
应用更新。警告
使用JobWrapper进行插入,因为它具有REPLACE冲突策略,如果它总是生成entityId,则会导致额外的位置。
结果
运行上述结果:-
职务表:-
位置表格:-
你问:
在插入查尔兹(位置)时,如何确保与正确的父项(作业)的关系?
我认为上面的例子说明了如何。
mrfwxfqh2#
JobWrapper
没有关联的表。注意,它很适合从数据库中拉取,因为它会从Location
表 * 和Job
表 * 中抓取,但是用JobWrapper
插入数据库是没有意义的,因为没有关联的表。相反,您需要分别插入
Job
s和Location
s。数据库可以一起查询它们,因为它们是由jobid
和parentid
相关的,所以您不必担心它们之间的关系丢失,并且您仍然可以查询您的JobWrapper
。如果给出了我上面的解释,你仍然认为你应该能够插入一个
JobWrapper
,那么你可以用这样的方法创建一个仓库:其中
insertJob
插入单个Job
,insertLocations
插入Location
的列表。