尝试更新时 UNIQUE 约束失败

UNIQUE constraint failed while trying to Update

我正在尝试更新 Room 数据库数据,但收到此错误。尝试更新项目时是否需要具有唯一 ID?我试图找到如何解决此错误的解决方案,但主要围绕插入操作(插入操作有效)或其他编程语言的解决方案。

错误:

 android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: Plant.plant_id (code 1555 SQLITE_CONSTRAINT_PRIMARYKEY)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:796)
        at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
        at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
        at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:51)
        at androidx.room.EntityInsertionAdapter.insert(EntityInsertionAdapter.java:64)
        at com.example.plantmanagement.dao.PlantOperations_Impl.insertPlant(PlantOperations_Impl.java:136)
        at com.example.plantmanagement.repository.PlantRepository.insertPlant(PlantRepository.kt:17)
        at com.example.plantmanagement.viewmodel.PlantViewModel$insertPlant.invokeSuspend(PlantViewModel.kt:25)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:342)
        at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30)
        at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:27)
        at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:109)
        at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:158)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
        at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:49)
        at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
        at com.example.plantmanagement.viewmodel.PlantViewModel.insertPlant(PlantViewModel.kt:24)
        at com.example.plantmanagement.activity.Edit_Plant$onCreate.onClick(Edit_Plant.kt:98)
        at android.view.View.performClick(View.java:6597)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
        at android.view.View.performClickInternal(View.java:6574)
        at android.view.View.access00(View.java:778)
        at android.view.View$PerformClick.run(View.java:25885)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

实体class:

Entity(tableName = "Plant")
data class Plant(

        @PrimaryKey(autoGenerate = true) var plant_id:Long,
        @ColumnInfo (name="plant_name") var name: String,
        //@Embedded var type: Plant_Category,
        @ColumnInfo(name= "plant_image", typeAffinity = ColumnInfo.BLOB) var image: ByteArray,
        @ColumnInfo(name="plant_type_name") var type:String ="",
        @ColumnInfo(name="plant_type_water")var water_time: String ="",
        @ColumnInfo(name="plant_type_details")var details: String = "",


        )

道class:

@Dao
interface PlantOperations {
    @Query("SELECT * FROM Plant")
    fun getAll(): Flow<List<Plant>>


    @Insert
    fun insertAll(vararg plant: Plant?)
    @Insert
    fun insertPlant(plant: Plant)
    @Query("DELETE  FROM Plant WHERE plant_id = :id")
    fun delete(id: Long)

    @Update(onConflict = OnConflictStrategy.REPLACE)
    fun updatePlant(plant: Plant)}

我还确保没有插入不同的 ID。

我将不胜感激。

您不是在更新记录,而是在尝试插入主键值相同的新记录。这在堆栈跟踪中可见

at com.example.plantmanagement.repository.PlantRepository.insertPlant(PlantRepository.kt:17)

所以为了更新记录,你需要调用updatePlant方法。

此外,在 update 的情况下,我没有看到 onConflict = OnConflictStrategy.REPLACE 有任何用途,您可能希望将其与 insert 方法一起使用。所以将您的 insertupdate 方法更新为

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertPlant(plant: Plant)

@Update
fun updatePlant(plant: Plant)