首页 > 解决方案 > 房间更新不起作用(尝试了许多变化)

问题描述

好的,我有两个相关的实体。ConnectionEntity 和 ChatEntity。它们之间的一对多关系。一个连接可以有多个聊天。

让我们看看我是如何定义连接实体的

  1. 连接实体(INT 类型的 id 为主键,自动生成设置为 TRUE)
  2. partner_uid 列是唯一列

让我们看看我是如何定义聊天实体的

  1. 聊天实体(INT 类型的 id 为主键,自动生成设置为 TRUE)
  2. message_id 列是唯一列
  3. 此外,chat_partner_uid 指的是 ConnectionEntity 的 partner_uid(chatEntity 中的 chat_partner_uid 指的是子列,而 connectionEntity 中的 partner_uid 指的是父列,这是一对多的关系)

什么有效:

  1. 插入连接实体有效
  2. 删除 connectionEntity 或所有实体有效

问题是什么:

  1. 更新操作不起作用。我尝试了所有冲突策略,还尝试通过首先获取 id 来传递具有自动生成的 id 的同一实体

我做了什么:

  1. 我关注了一些堆栈溢出帖子并使用了 upsert 策略
  2. 首先尝试使用 onconflict = ABORT 插入,如果该行已经存在则捕获异常,然后调用 update
  3. 我还首先从房间获取 ID,因为 ID 是自动生成的,使用相同的 ID 填充新的连接实体并调用更新,但它不起作用。数据保持不变

我的 ConnectionEntity 类

@Entity(tableName = "connection_table", indices = [Index("partner_uid", unique = true)])
data class ConnectionEntity(
    @PrimaryKey(autoGenerate = true)
    var id: Int? = null,

    @ColumnInfo(name = "partner_uid")
    var partnerUid: String,

    var connectionMedium: String = ValueStrings.connectionMediumChat.stringValue,
    var firstName: String = "",
    var isDisconnected: Boolean = false,
    var profileImageUrl: String = "",
    var unReadMessages: Int = 0
)

我的 ChatEntity 类

@Entity(
    tableName = "chat_table",
    indices = [Index("message_id", unique = true)],
    foreignKeys = [
        ForeignKey(
            entity = ConnectionEntity::class,
            parentColumns = ["partner_uid"],
            childColumns = ["chat_partner_uid"],
            onDelete = CASCADE,
            deferred = true
        )
    ]
)
data class ChatEntity(
    @PrimaryKey(autoGenerate = true)
    var id: Int? = 0,

    @ColumnInfo(name = "message_id")
    var messageId: String,

    var fromId: String = "",
    var messageText: String = "",
    var messageTime: Int = 0,
    var toId: String = "",

    @ColumnInfo(name = "chat_partner_uid", index = true)
    var chatPartnerUid: String
)

这是DAO

@Dao
interface ConnectionChatDao {
    @Insert(onConflict = OnConflictStrategy.ABORT)
    suspend fun insertConnection(connectionEntity: ConnectionEntity)

    @Update
    suspend fun updateConnection(connectionEntity: ConnectionEntity)

    @Transaction
    suspend fun upsert(connectionEntity: ConnectionEntity) {
        try {
            insertConnection(connectionEntity)
        } catch (e: SQLiteConstraintException) {
            val currentId = getConnection(connectionEntity.partnerUid)?.id
            connectionEntity.id = currentId
            updateConnection(connectionEntity)
        }
    }

    @Query("DELETE FROM connection_table")
    suspend fun flushAllData()
}

根据要求...这就是我调用该函数的方式。我使用视图模型中的存储库模式

class MainViewModel(application: Application): AndroidViewModel(application) {
    val repository = AccessRepository(ConnectionChatUserDatabase.getInstance(application))

    fun updateConnectionNameInRoom() {
        viewModelScope.launch {
            val connectionEntity = ConnectionEntity(
                partnerUid = "def",
                connectionMedium = "Chat",
                firstName = "Jake",
                isDisconnected = false,
                profileImageUrl = "www.google.com",
                unReadMessages = 0
            )

            val response = repository.upsertData(connectionEntity)
            if (!response.isOperationComplete) {
                Log.d("MainActivity", "There was an error")
            } else {
                Log.d("MainActivity", "Success")
            }
        }
    }
}

这是存储库类

class AccessRepository(private val database: ConnectionChatUserDatabase) {

    //Room
    suspend fun upsertDataToRoom(connectionEntity: ConnectionEntity): AccessRepositoryProperty<String>{
        return try {
            database.connectionChatDao.upsert(connectionEntity)
            AccessRepositoryProperty(null, property = "Success", isOperationComplete = true)
        } catch (e: Exception) {
            AccessRepositoryProperty(e, property = "upsertError", isOperationComplete = false)
        }
    }
}

标签: androidkotlinandroid-roomandroid-jetpack

解决方案


推荐阅读