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

Android Room 2.7.2 出现NoSuchElementException(Key缺失)问题的解决求助

Android Room 2.7.2 出现NoSuchElementException(Key缺失)问题的解决求助

大家好,我在使用Room 2.7.2开发时碰到了一个致命异常,实在摸不着头脑,来求助各位大佬!

异常栈信息如下:

Fatal Exception: java.util.NoSuchElementException
Key 1855838 is missing in the map.
kotlin.collections.MapsKt__MapWithDefaultKt.getOrImplicitDefaultNullable (MapWithDefault.kt:24)
kotlin.collections.MapsKt__MapsKt.getValue (Maps.kt:370)
android.persistence.phonelines.ConnectedUserDao_Impl.getFullConnectedUsersFlowByOrderNr$lambda$6 (ConnectedUserDao_Impl.kt:342)
android.persistence.phonelines.ConnectedUserDao_Impl.$r8$lambda$43VE92PoOM1yQT3OPmuzeuKB5FM
android.persistence.phonelines.ConnectedUserDao_Impl$$ExternalSyntheticLambda2.invoke (D8$$SyntheticClass)
androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend (DBUtil.kt:68)

先给大家看下我的数据结构:

组合数据类 FullConnectedUser

data class FullConnectedUser(
    @Embedded val user: ConnectedUser,
    @Relation(
        parentColumn = "phoneLineOid",
        entityColumn = "oid"
    )
    private val _phoneLines: List<PhoneLine>,
    @Relation(
        parentColumn = "associatedAddressableOid",
        entityColumn = "oid"
    )
    private val _addressables: List<Addressable>
)

实体类 ConnectedUser

@Entity(tableName = "connected_users")
data class ConnectedUser(
    @PrimaryKey val oid: String,
    val phoneLineOid: String,
    val associatedAddressableOid: String,
    val isIncoming: Boolean,
    val isOutgoing: Boolean,
    val editable: String,
    val orderNumber: Int
)

实体类 PhoneLine

@Entity(tableName = "phone_lines")
data class PhoneLine(
    // Phone line OID
    @PrimaryKey val oid: String,
    val associatedAddressableOid: String,
    val userPhoneLineOid: String,
    val commonName: String,
    val externalNumber: String,
    val callerName: String,
    val unreadRecentContactsCount: Int,
    val fetchedUntil: String
)

我的DAO查询方法是这样的:

@Query("SELECT * FROM connected_users ORDER BY orderNumber")
fun getFullConnectedUsersFlowByOrderNr(): Flow<List<FullConnectedUser>>

在Compose页面里,我用collectAsState来观察这个Flow:

val connectedUsersListState: List<FullConnectedUser> by viewModel.getFullConnectedUsersFlowByOrderNr().collectAsState(initial = emptyList())

数据插入的逻辑是分开异步执行的:

viewModel.viewModelScope.launch(coroutineExceptionHandler) {
    kotlin.runCatching {
        viewModel.fetchPhoneLines() // 从接口拉取并插入phone_lines表
    }
    kotlin.runCatching {
        viewModel.fetchConnectedUsers() // 从接口拉取并插入connected_users表
    }
}

我发现快速打开这个Fragment然后立即返回时,异常很容易复现。看异常信息,问题出在Room自动生成的DAO实现类里,尝试从Map中获取某个Key但没找到。我猜测是因为两个表的数据是分开插入的,当Flow触发查询时,某个ConnectedUser记录的phoneLineOid在phone_lines表里还没有对应的记录,导致Room关联查询时出错?

想请教下各位,这种情况该怎么处理?有没有办法让Room在关联数据不存在时不抛出异常,而是返回空List或者其他合法状态?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 07:33:02