kotlinsqliteandroid-room

Many to Many Relationship in Room: Cannot find the child entity column


I have a Room database with a many to many relationship between BusStops and Lines

@Entity(tableName = "BusStops")
data class BusStopEntity(
    @PrimaryKey val id: Int = 0,
    val name: String,
    val lat: Double,
    val lon: Double
)

@Entity(tableName = "Lines")
data class LineEntity(
    @PrimaryKey val id: Int = 0,
    val name: String
)

@Entity(primaryKeys = ["busStopId", "lineId"])
data class BusStopLineEntity(
    val busStopId: Int,
    val lineId: Int
)

I use this data class to have the relationship:

data class LineWithBusStops(
    @Embedded val line: LineEntity,
    @Relation(
        parentColumn = "id",
        entityColumn = "busStopId",
        associateBy = Junction(BusStopLineEntity::class)
    )
    val busStops: List<BusStopEntity>
)

But I get an error on the @Relation line entityColumn = "busStopId"

Cannot find the child entity column busStopId in com.local.model.BusStopEntity. Options: id, name, lat, lon

If I change busStopId to id, I got even more errors.

Any ideas?


Solution

  • The issue is that the Entity is a field/column in the entity(table) that is referenced via the association (intermediate table) rather than a column in the associative/intermediate table.

    That is the Entity is a BusStopEntity, which only has fields/columns id, name, lat and long i.e. there is no busStopId field/column.

    busStopId is a column in the associative/intermediate BusStopLineEntity table.

    You likely want to use id for the entityColumn of the @Relation.

    You can specify the respective columns of the intermediate table using the parentColumn and entityColumn parameters of the Junction

    So the following could be used:-

    data class LineWithBusStops(
        @Embedded val line: LineEntity,
        @Relation(
            parentColumn = "id", /* the column in the parent table i.e. the Embedded */
            entityColumn = "id", /* the column in the child table i.e. the Relation */
            associateBy = Junction(
                BusStopLineEntity::class, /* the entity of the intermediate table */
                parentColumn = "lineId", /* the column in the intermediate table that references the parent row */
                entityColumn = "busStopId" /* the column in the intermediate table that references the child */
            )
        )
        val busStops: List<BusStopEntity>
    )