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

Android Room查询SQLite实体列表失败,测试报数组越界异常

排查Room查询getAllScheduledAlarmResources返回空列表的问题

以下是针对该问题的具体排查步骤:

1. 核对Dao查询语句的正确性

先检查getAllScheduledAlarmResources()的@Query注解内容,重点确认WHERE条件是否匹配业务逻辑与Converter规则:

@Dao
interface AlarmResourceDao {
    // 单个查询正常的方法
    @Query("SELECT * FROM alarm_resources WHERE id = :id")
    suspend fun getAlarmResourceById(id: Long): AlarmResourceEntity?

    // 重点检查这个查询的条件
    @Query("SELECT * FROM alarm_resources WHERE is_scheduled = 'Y'")
    suspend fun getAllScheduledAlarmResources(): List<AlarmResourceEntity>
}
  • 确认字段名:实体类中isScheduled字段默认会被Room映射为is_scheduled(驼峰转下划线),如果手动指定了@ColumnInfo(name = "custom_name"),查询语句要对应这个自定义名称。
  • 确认布尔值对应字符:如果你的BooleanConverter将true转成'Y',查询条件必须用'Y',不能用1或'T'这类不匹配的值。

2. 验证BooleanConverter的转换逻辑

检查转换器的双向转换是否一致,避免存和读的规则不匹配:

class BooleanConverter {
    @TypeConverter
    fun booleanToChar(value: Boolean?): Char {
        // 确认转换规则,比如true对应'Y',false对应'N'
        return value?.let { if (it) 'Y' else 'N' } ?: 'N'
    }

    @TypeConverter
    fun charToBoolean(value: Char?): Boolean {
        // 这里要和上面的规则对应,比如只有value为'Y'时返回true
        return value == 'Y'
    }
}

如果存的时候用'1'表示true,但查的时候用'Y',会直接导致查询不到数据。

3. 查看数据库中的实际数据

用Android Studio的Database Inspector连接测试设备,直接查看alarm_resources表内容:

  • 找到单个查询能返回的记录,查看is_scheduled字段的存储值是否符合Converter规则。
  • 确认表中是否存在其他is_scheduled值匹配查询条件的记录,避免测试数据本身就不满足筛选要求。

4. 检查实体类的注解配置

确认AlarmResourceEntity的注解是否正确:

@Entity(tableName = "alarm_resources")
@TypeConverters(BooleanConverter::class)
data class AlarmResourceEntity(
    @PrimaryKey(autoGenerate = true) val id: Long = 0,
    val isScheduled: Boolean,
    // 其他字段...
)
  • 确保@TypeConverters注解被正确应用(可放在实体类、Dao类或Database类上),避免Converter未生效导致布尔值存储异常。
  • 检查是否有其他字段的@ColumnInfo注解导致字段名与查询语句不匹配。

5. 排查数据库迁移或初始化问题

如果测试基于已有数据库:

  • 确认数据库版本更新时是否编写了正确的迁移脚本,比如之前用整数存储布尔值,现在改为字符,迁移时需要将旧数据的1/0转换为'Y'/'N'。
  • 如果是测试中初始化数据库,检查测试数据的插入逻辑,是否正确设置了isScheduled = true,避免插入时该字段值为false导致查询不到。

6. 添加日志调试测试流程

在测试代码中添加日志,打印查询前的数据库状态和查询结果:

@Test
fun testGetAllScheduledAlarms() = runTest {
    // 插入一条isScheduled为true的测试数据
    val testAlarm = AlarmResourceEntity(isScheduled = true)
    dao.insertAlarmResource(testAlarm)

    // 先查询所有记录,确认数据已插入
    val allAlarms = dao.getAllAlarmResources() // 需新增一个查询所有的Dao方法
    Log.d("TestDebug", "所有闹钟数量: ${allAlarms.size}, 详情: $allAlarms")

    // 执行目标查询
    val scheduledAlarms = dao.getAllScheduledAlarmResources()
    Log.d("TestDebug", "已调度闹钟数量: ${scheduledAlarms.size}")

    // 断言验证
    assert(scheduledAlarms.isNotEmpty())
}

通过日志确认数据是否真的被插入,以及查询条件是否筛选出正确的记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 19:31:18