尝试更新时 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
方法一起使用。所以将您的 insert
和 update
方法更新为
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertPlant(plant: Plant)
@Update
fun updatePlant(plant: Plant)
我正在尝试更新 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
方法一起使用。所以将您的 insert
和 update
方法更新为
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertPlant(plant: Plant)
@Update
fun updatePlant(plant: Plant)