I am having issues with defining a relationship between two entities. The relation is one-to-one. Every Device is assigned to one room.
Device entity:
@Entity
data class Device(
@PrimaryKey(autoGenerate = false) val ipAddress: String,
val deviceName: String,
val type: Int,
val uniqueRoomId: Int
) {
@Ignore
val status: DeviceStatus = DeviceStatus.Off
}
Room entity
@Entity
data class Room(
@PrimaryKey(autoGenerate = true) val roomId: Int,
val name: String
)
Device and room object:
data class DeviceAndRoom(
@Embedded val room: Room,
@Relation(
parentColumn = "roomId",
entityColumn = "uniqueRoomId",
entity = Device::class
)
val device: Device
)
DeviceDao:
@Dao
interface DeviceDao {
@Transaction
@Query("SELECT * FROM Device")
fun getAllDeviceAndRooms(): LiveData<List<DeviceAndRoom>>
[...]
}
But I get the following build error:
The columns returned by the query does not have the fields [roomId,name] in com.test.mytestapp.models.DeviceAndRoom even though they are annotated as non-null or primitive. Columns returned by the query: [ipAddress,deviceName,type,uniqueRoomId]
I followed the official android guidelines but there are further articles which describe the same procedure, e.g. Database relations with Room
I have no clue what's wrong. Maybe someone has an idea.
CodePudding user response:
For that relationship (the Room (embedded) with the Devices (relationship)) you query the parent so :-
@Query("SELECT * FROM room")
fun getAllDeviceAndRooms(): LiveData<List<DeviceAndRoom>>
- names should probably be RoomAndDevice
i.e it cannot find the roomid and name columns in the device table as they are in the room table. It is from each of the retrieved room(s) that the device(s) is(are) then retrieved via an underlying query, along the lines of SELECT * FROM the_relationship_entity WHERE entityColumn = parentColumn
and hence why the @Trasnaction
is recommended.
If you want the Devices with their Room then you'd use :-
data class DeviceAndRoom(
@Embedded val device: Device,
@Relation(
entityColumn = "roomId",
parentColumn = "uniqueRoomId",
entity = Room::class
)
val room: Room
)
along with :-
@Transaction
@Query("SELECT * FROM Device")
fun getAllDeviceAndRooms(): LiveData<List<DeviceAndRoom>>