Search code examples
androidkotlinexceptioninsertandroid-room

RoomDatabase Insert doesnt work and no error to find why


i am using room database when i insert data, i can not read it again and i dont know what is the problem because there is no error for sql

the question is what is the problem and how sql throws exertion

Entity

@Entity(tableName = "boards_table")
class BoardModel {
    @PrimaryKey
    var  Id = ""
    var Title =""
}

id is not auto increase becaus it already created, i am reading an API

DAO


@Dao
interface BoardDAO {


    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun addBoard(board:BoardModel)

    @Query("SELECT * FROM boards_table")
    fun readAllData(): LiveData<List<BoardModel>>

    @Query("DELETE FROM boards_table")
        suspend fun deleteAllBoard()
    @Delete
    suspend fun deleteBoard(board:BoardModel)



}

write in activity

private lateinit var boardDao:BoardDAO
appDb = NimaDatabase.getDatabase(this)

// tempBoardlist from api and it is OK
for (board in tempBoardlist){
  GlobalScope.launch {
    boardDao.addBoard(board.toBoardModel())
   }
 }

read in activity

var boardlist = boardDao.readAllData().value

i used @Throws(SQLException::class) but not worked

// this works fine 
// class to get from API easily
class board() {
    val _id: String = ""
    val title: String = ""
}

//Covert it to BoardModel
fun board.toBoardModel() : BoardModel
{
    val b =  BoardModel()
    b.Id = _id
    b.Title = title
    return b
}

Solution

  • Each Room entity must have access to it, You can make sure Room has access to a field either by making it public or by providing getter and setter methods for it.

    Please read room defining-data

    You need to define the data class to have access to setter and getter methods.

    @Entity(tableName = "boards_table")
    data class BoardModel(
    @PrimaryKey
    val  id : Long,
    val title : String
     )
    

    In Activity, it's recommended to use activity lifecycleScope to launch coroutines. Read Use Kotlin coroutines with lifecycle-aware components

    lifecycleScope.launch {
       // for loop must be in coroutine scope
       for(data in list) boardDao.insert(data) 
    }
    

    This var boardlist = boardDao.readAllData().value it will return null

    LiveData is an observable data holder. You need to register as an observer.

    In Activity:

        // Create the observer which updates the UI.
        val nameObserver = Observer<List<BoardModel>> { list ->
            // Update the UI Hire.
            if(list != null) // update list, recyclerview, etc...
        }
        lifecycleScope.launch {
            boardDao.readAllData().observe(this@MainActivity,nameObserver)
        }