I have these Entities I would like to insert in the database: It seems I can't get to build the nested entities right. I need your help in this
[1] ArticleEntity
@Entity(
tableName = "articles",
foreignKeys = [
ForeignKey(
entity = PartCargo::class,
parentColumns = ["tId"],
childColumns = ["partTId"],
onDelete = ForeignKey.CASCADE
)
]
)
data class ArticleEntity(
@PrimaryKey(autoGenerate = true)
val tId: Long = 0,
val partTId: Long = -1,
val id: String?,
val name: String?,
) : Serializable
[2] PartEntity
@Entity(
tableName = "parts",
foreignKeys = [
ForeignKey(
entity = DetailsCargo::class,
parentColumns = ["tId"],
childColumns = ["detailsTId"],
onDelete = ForeignKey.CASCADE
)
]
)
data class PartCargo(
@PrimaryKey(autoGenerate = true)
val tId: Long = 0,
val detailsTId: Long = -1,
val id: String?,
val name: String?,
) : Serializable
data class PartEntity(
@Embedded
val part: PartCargo,
@Relation(parentColumn = "tId", entityColumn = "partTId")
val partArticles: List<ArticleEntity>?
) : Serializable
[3] DetailsEntity
@Entity(tableName = "details")
data class DetailsCargo(
@PrimaryKey(autoGenerate = true)
val tId: Long = 0,
val id: String?,
val name: String?
) : Serializable
data class DetailsEntity(
@Embedded
val details: DetailsCargo,
@Relation(parentColumn = "tId", entityColumn = "detailsTId")
val parts: List<PartEntity>?
) : Serializable
This is DetailsDAO
@Dao
interface DetailsDAO {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertPartCargo(parent: PartCargo): Long
@Transaction
fun insertAllParts(parentId: Long, parts: List<PartEntity>) {
parts.forEach { part ->
val cargoParentId = insertPartCargo(part.part.copy(detailsTId = parentId))
part.partArticles?.let { items ->
val children = items.map { it.copy(partTId = cargoParentId) }
insertArticleEntities(children)
}
}
}
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertDetailsCargo(parent: DetailsCargo): Long
@Transaction
fun insertDetails(details: DetailsEntity) {
val parentId = insertDetailsCargo(details.details)
details.parts?.let { items ->
insertAllParts(parentId, items)
}
}
@Transaction
@Query("SELECT * FROM details WHERE :id = id")
fun getDetails(id: String): DetailsEntity?
}
Now, I get this error while building the app:
Cannot find the child entity column `detailsTId` in PartEntity.
- Are my entities built right?
- If not, what is the solution?
Thanks in advance
Not fully checking the relationships/entities
BUT if you are using hierarchical (nested) POJO classes then the
@Relationannotation that is lower (a child of a child) should reflect the Entity (the table where the columns exist) not the POJO.@Relationhas an entity parameter, this should be used in such cases, as such I believe that your issue may be resolved by using:-@Entityannotated class, has the fields (columns) that the underlying queries will extract.@Relationannotation.Without (comment out) then:-
With:-
You may wish to heed the 3 warnings and use the
@ColumnInfoon the respective fields e.g.Additional Re Comment
It will/should retrieve everything as per the POJOs the @Relation is telling Room how to get the data from the tables/relationships to build the resultant POJO(s).
Perhaps consider this result (code follows):-
Based upon your code(amended as per the question, also with some extra code to use just the single Dao) this is some activity code (note for the brevity of the demo main thread has been used) that generated result above:-
@Entityannotated being used (i.e. dc is a DetailsEntity object not a DetailsCargo, p is a PartsEntity object not a PartsCargo object)