Insert Query Room OnConflictStrategy.REPLACE

Viewed 41

Inerface :

@Dao
interface ProductDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertProducts(dataUser: ArrayList<Products>)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertVariants(dataUser: Variants)
}

I want to replace the old product list and insert new product list even if the primary key of old and new product list not same

Product Entity :

@Entity(tableName = "Product")
data class Products (

  @PrimaryKey(autoGenerate = false)
  @ColumnInfo(name = "id")
  var id : Int = 0,
 
  @ColumnInfo(name = "image")
  var image: String? = null,

  @ColumnInfo(name = "other_images")
  var other_images: List<String>  = listOf(),

  @ColumnInfo(name = "variants")
  var variants : List<Variants> = listOf()

)

Variant Entity :

@Entity(tableName = "Variant",
        foreignKeys = [
        ForeignKey(
          entity = Products::class,
          parentColumns = arrayOf("id"),
          childColumns = arrayOf("product_id"),
          onDelete = ForeignKey.CASCADE
        )
])
data class Variants (

  @PrimaryKey(autoGenerate = false)
  @ColumnInfo(name = "id")
  var id : Int  = 0,

  @ColumnInfo(name = "product_id", index = true)
  var product_id : String?  = null,

  @ColumnInfo(name = "stock")
  var stock : String?  = null,

  @ColumnInfo(name = "varient_status")
  var varient_status : String?  = null,

  @ColumnInfo(name = "measurement_unit_name")
  var measurement_unit_name : String?  = null,

  @ColumnInfo(name = "stock_unit_name")
  var stock_unit_name : String?  = null,

  @ColumnInfo(name = "cart_count")
  var cart_count : String?  = null,

)

ProductWithVariants Relation :

data class ProductWithVariants(
    @Embedded val product: Products,
    @Relation(
        parentColumn = "id",
        entityColumn = "product_id"
    )
    val variants: MutableList<Variants>
)

This the area where i delete the old records in Product table and Variant table and need to add the new record into the table and need to display it in recyclerview .

ViewModel Success Response :

fun productlist() = viewModelScope.launch(Dispatchers.IO) {
    productist.collectLatest {
        when(it) {
            Resource.Empty -> {
                Log.e("catdata",""+"empty")
            }
            is Resource.Failure -> {
                Log.e("catdata",""+"failure")
            }
            Resource.Loading -> {

            }
            is Resource.Success -> {
                val response = it.value
                productsDao.deleteAllProducts()
                productsDao.insertProducts(response.data)
                for (i in 0 until response.data.size) {
                    val product: Products = response.data.get(i)
                    for (j in 0 until product.variants.size) {
                        val variants: Variants = product.variants.get(j)
                        productsDao.insertVariants(variants)
                    }
                }
            }
        }
    }
}

Main Activity where i used to call the viewmodel and get response from pagingsource using kotlin flow :

 val adapter = ProductListAdapter()
        binding.ProductRecyclerView.adapter = adapter.withLoadStateFooter(ProductLoadStateAdapter())

        lifecycleScope.launch {
            productviewModel.data.collectLatest {
                adapter.submitData(it)
            }
        }
        binding.apply {
            subcatone.setOnClickListener {
                Log.e("test", "checkone")
                viewModel.getproductlist("218")
            }
            subcattwo.setOnClickListener {
                Log.e("test", "checktwo")
                viewModel.getproductlist("217")
            }
        }

This is the Viewmodel to call database from MainActivity :

@HiltViewModel
class productViewModel @Inject constructor(val productsDao: ProductDao) : ViewModel() {

    val data = Pager(PagingConfig(pageSize = 20, enablePlaceholders = false, initialLoadSize = 20)) {
        ProductPagingSource(productsDao)
    }.flow.cachedIn(viewModelScope)
}
1 Answers

You need to remove old data and insert new ones again.

@Dao
interface ProductDao {

    ...

    
    @Query("DELETE FROM PRODUCTS")
    suspend fun deleteAllProducts()
}

And before inserting new items, delete old items:

val dao = //....
scope.launch {
    // first delete the items
    dao.deleteAllProducts()

    // insert new items
    dao.insertProducts(...)

}
Related