https://kotlinlang.org logo
#android
Title
# android
d

Duchynko

11/22/2019, 1:00 PM
Hello guys. I have a problem with my local room database. Domain model
Copy code
@Entity(tableName = "students")
data class Student(
    @PrimaryKey(autoGenerate = true)
    val id: Int? = null,
    var studentName: String,
    val studentId: String,
    var purchaseDate: String,
    val comment: String
)
DAO
Copy code
@Dao
interface StudentDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun upsert(student: List<Student>)

    @Query("select * from students")
    fun getStudents(): LiveData<List<Student>>
}
Repository methods for upserting and getting List of Students
Copy code
private fun persistFetchedStudents(fetchedStudents: StudentsResponse) {
    GlobalScope.launch(<http://Dispatchers.IO|Dispatchers.IO>) {
        Log.i("StudentRepositoryImpl", "Called from persistFetchedStudents: fetchedStudents.students.size = " + fetchedStudents.students.size)
        studentsDao.upsert(fetchedStudents.students)
    }
}
Log -> fetchedStudents.students.size = 140
Copy code
private fun isFetchStudentNeeded(): Boolean {
    Log.i("StudentRepositoryImpl", "Called from isFetchStudentNeeded: studentsDao.getStudents().value = " + studentsDao.getStudents().value)
    return studentsDao.getStudents().value.isNullOrEmpty()
}
Log -> studentsDao.getStudents().value = null Is there anything I'm doing wrong? I can't see any issue myself. Thanks for any help 🙂
g

Giorgos Neokleous

11/22/2019, 1:03 PM
You can format your code with triple quotes "```"
👍🏼 1
d

dino9

11/22/2019, 1:08 PM
You can probably use stetho and debug whether data is getting updated into DB first.
d

Duchynko

11/22/2019, 1:26 PM
Also, my dependency injection and Application class.
Copy code
class StudentSportApplication: Application(), KodeinAware {
    override val kodein = Kodein.lazy {
        import(androidXModule(this@StudentSportApplication))

        bind() from singleton { StudentDatabase(instance()) }
        bind() from singleton { instance<StudentDatabase>().studentDao() }
...
And Database class
Copy code
@Database(
    entities = [Student::class],
    version = 1
)

abstract class StudentDatabase : RoomDatabase() {
    abstract fun studentDao(): StudentDao

    companion object {
        @Volatile private var instance: StudentDatabase? = null
        private val LOCK = Any()

        operator fun invoke(context: Context) = instance ?: synchronized(LOCK) {
            instance ?: buildDatabase(context).also { instance = it }
        }

        private fun buildDatabase(context: Context) =
            Room.databaseBuilder(context.applicationContext,
                StudentDatabase::class.java, "students.db")
                .build()
    }
}
@dino9 data are being in the database.
Copy code
@Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(students: List<Student>) : List<Long>
This is returning me list of IDs
d

dino9

11/22/2019, 1:47 PM
Aren't you suppose to observe livedata? 🤔
Copy code
dao.getStudents().observe(this, new Observer<List<Student>>() {
@Override
public void onChanged(@Nullable List<Student> student) { }});
d

Duchynko

11/22/2019, 1:48 PM
Copy code
init {
        studentNetworkDataSource.downloadedStudents.observeForever { newStudents ->
            Log.i("StudentRepositoryImpl", "Called from init method.")
            persistFetchedStudents(newStudents)
        }
    }
d

dino9

11/22/2019, 1:50 PM
I guess you're observing network response here. I shared for database.
d

Duchynko

11/22/2019, 3:59 PM
@dino9 Make sense. I'm returning List<Student> instead of LiveData. As you can't just return LiveData. Maybe it would also work with an Observer as you suggested.
3 Views