You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Room定义一对一关联构建报错:查询返回结果缺少对应列

问题根因

你当前的报错是因为Room框架的关联查询规则不匹配:

  • 你在DeviceAndRoom中用@Embedded注解标记了Room实体,这代表Room框架会默认将你执行的查询SQL返回的字段,映射到这个被@Embedded修饰的实体的所有属性上
  • 你Dao中执行的是SELECT * FROM Device,仅返回Device表的ipAddress、deviceName、type、uniqueRoomId四个字段,完全没有Room实体需要的roomId、name字段,因此直接触发字段缺失的报错
    同时你当前的关联方向也和你的业务需求不匹配:你的业务是每个Device归属唯一Room,属于以Device为主体关联查询所属Room的场景,你当前写的关联逻辑是以Room为主体关联查询下属Device,方向是反的。

修复方案(适配你的业务需求)

1. 调整关联组合类的结构

将DeviceAndRoom的@Embedded改为修饰Device实体,调整@Relation的关联字段对应关系:

data class DeviceAndRoom(
    // 主实体改为Device,匹配你查询Device表的逻辑
    @Embedded val device: Device,

    @Relation(
        parentColumn = "uniqueRoomId", // Device表中关联Room的外键
        entityColumn = "roomId", // Room表的主键
        entity = Room::class
    )
    val room: Room
)

2. (可选)添加唯一约束避免一对多数据异常

因为你的业务是一对一关联,为了避免出现一个Room对应多个Device的脏数据,可以在Device实体的类注解中添加唯一索引:

@Entity(
    indices = [Index(value = ["uniqueRoomId"], unique = true)]
)
data class Device(
    @PrimaryKey(autoGenerate = false) val ipAddress: String,
    val deviceName: String,
    val type: Int,
    val uniqueRoomId: Int
) {
    @Ignore
    val status: DeviceStatus = DeviceStatus.Off
}

3. Dao代码无需修改

你原来的Dao查询逻辑已经适配调整后的关联类,构建即可正常运行。


备选方案(如果你的需求是查询每个Room对应的Device)

如果你的业务实际是查询每个Room下的设备,不需要调整关联类结构,只需要修改Dao的查询SQL为主表查Room即可:

@Dao
interface DeviceDao {
    @Transaction
    @Query("SELECT * FROM Room") // 改为查询Room表,提供@Embedded需要的roomId、name字段
    fun getAllRoomAndDevices(): LiveData<List<DeviceAndRoom>>
}

内容的提问来源于stack exchange,提问作者linux_lover

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 12:36:05