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
相关产品推荐
相关产品推荐

