Home > OS >  Avoid duplicate entries in room Database
Avoid duplicate entries in room Database

Time:09-10

I am trying to make a function which will check whether this id is already present or not in the database, But it is not working as required.It take the insert value in database.

private fun CheckDuplicateId(id:String,donorDao:DonorDao):Boolean{
        var result=true
        lifecycleScope.launch {
            donorDao.fetchAllDonor().collect(){
                var Donorlist=ArrayList(it)
                for(item in Donorlist){
                    if (item.id==id){
                        result=false
                    }
                }
            }
        }
        return result
    }

I am using this function in while inserting the entry

private fun addRecord(donorDao:DonorDao){
        val Id:String=binding?.etDonorId?.text.toString()
        val bloodGr=binding?.etDonorBloodgroup?.text.toString()
        if(Id.isNotEmpty() && bloodGr.isNotEmpty() && CheckDuplicateId(Id,donorDao)){
            lifecycleScope.launch {
                donorDao.insert(DonorEntity(id = binding?.etDonorId?.text.toString(), bloodGroup = bloodGr))
                Toast.makeText(applicationContext, "Record saved", Toast.LENGTH_SHORT).show()
            }
        }else{
            Toast.makeText(this,"duplicate value",Toast.LENGTH_SHORT).show()
        }
    }

here donor entity

@Entity(tableName = "donor-table")
data class DonorEntity(
    @PrimaryKey(autoGenerate = true)
    var sr_no:Int=0,
    var id:String="",
    var bloodGroup:String="")

here donor dao

@Dao
interface DonorDao {
    @Insert
    suspend fun insert(donorEntity:DonorEntity)
    @Update
    suspend fun update(donorEntity:DonorEntity)
    @Delete
    suspend fun delete(donorEntity:DonorEntity)
    @Query("SELECT*FROM `donor-table`")
    fun fetchAllDonor(): Flow<List<DonorEntity>>
    @Query("SELECT*FROM `donor-table` Where id=:id")
    fun fetchDonorById(id:Int): Flow<DonorEntity>
}

here the database

@Database(entities = [DonorEntity::class], version = 2)
abstract class DonorDatabase:RoomDatabase() {
    abstract fun donorDao():DonorDao

    companion object{
        @Volatile
        private var INSTANCE:DonorDatabase?=null
        fun getInstance(context: Context):DonorDatabase{
            synchronized(this){
                var instance=INSTANCE
                if (instance==null){
                    instance=Room.databaseBuilder(context.applicationContext,
                        DonorDatabase::class.java,"donor_database")
                        .fallbackToDestructiveMigration().build()
                }
                INSTANCE=instance
                return instance
            }
        }
    }

}

CodePudding user response:

Your method returning true immediately:

private fun CheckDuplicateId(id:String,donorDao:DonorDao):Boolean{
    var result=true
    lifecycleScope.launch {
        donorDao.fetchAllDonor().collect(){
            var Donorlist=ArrayList(it)
            for(item in Donorlist){
                if (item.id==id){
                    result=false
                }
            }
        }
    }
    return result // return true immediately
}

So, do it inside

private fun addRecord(donorDao:DonorDao){
    val Id:String=binding?.etDonorId?.text.toString()
    val bloodGr=binding?.etDonorBloodgroup?.text.toString()
    if(Id.isNotEmpty() && bloodGr.isNotEmpty()){
        lifecycleScope.launch {
            // check here CheckDuplicateId(Id,donorDao) synchronously

            donorDao.insert(DonorEntity(id = binding?.etDonorId?.text.toString(), bloodGroup = bloodGr))
            Toast.makeText(applicationContext, "Record saved", Toast.LENGTH_SHORT).show()
        }
    }else{
        Toast.makeText(this,"duplicate value",Toast.LENGTH_SHORT).show()
    }
}

CodePudding user response:

One way to do that is at DB level is using index. This will only insert if table as no with same id value. You can avoid select * query which would affect performance if you have many data in you case.

@Entity(tableName = "donor-table",indices = [Index(value = ["id"], unique = true)])
data class DonorEntity(
    @PrimaryKey(autoGenerate = true)
    var sr_no:Int=0,
    @ColumnInfo(name = "id")
    var id:String="",
    var bloodGroup:String="")
  • Related