Room DB에 초기데이터를 설정하는 것을 하고 있는데요, 결과만 말씀드리면 성공은 했습니다
근데 우연히 다른 코드를 작성하고 App Inspection 탭과 디버깅을 하면서
특정 상황에서만 DB에 초기데이터가 설정되는 것을 확인했는데요,
그 이유가 궁금합니다.
먼저 코드입니다.
----------------
DAO
@Dao
interface WorkoutListDao {
@Query("SELECT * FROM WorkoutList")
fun getWorkoutList() : LiveData<List<WorkoutList>>
@Insert
suspend fun insertWorkoutList(workoutList: WorkoutList)
}
Database
@Database(
entities = [WorkoutList::class],
version = 1
)
@TypeConverters(WorkoutListTypeConverter::class)
abstract class WorkoutListDatabase : RoomDatabase() {
abstract fun workoutListDao() : WorkoutListDao
companion object {
private var INSTANCE : WorkoutListDatabase? = null
@Synchronized
fun getDatabase(context: Context) : WorkoutListDatabase {
// if the INSTANCE is not null, then return it,
// if it is, then create the database
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
WorkoutListDatabase::class.java,
"workoutlist_db"
)
.addCallback(WorkoutListCallback(context))
.build()
INSTANCE = instance
instance
}
}
}
}
WorkoutListCallback
private const val WORKOUTLIST_JSON_FILE = "WorkoutList.json"
class WorkoutListCallback(private val context: Context) : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
CoroutineScope(Dispatchers.IO).launch {
fillWithStartingWorkoutList(context)
}
}
private suspend fun fillWithStartingWorkoutList(context: Context) {
val dao = WorkoutListDatabase.getDatabase(context).workoutListDao()
try {
val data = loadJsonData(context) // gson으로 인해 WorkoutList의 형태로 넘어옴
dao.insertWorkoutList(data)
} catch (e: JSONException) {
e.printStackTrace()
}
}
private fun loadJsonData(context: Context) : WorkoutList {
val assetManager = context.assets // assetManager 인스턴스 생성
val inputStream = assetManager.open(WORKOUTLIST_JSON_FILE)
BufferedReader(inputStream.reader()).use { reader ->// use는 사용후 열었던 스트림을 자동적으로 close 해줌
val gson = Gson()
return gson.fromJson(reader, WorkoutList::class.java)
}
}
}
ViewModel
class WorkoutListViewModel(application: Application) : AndroidViewModel(application){
private val workoutDao = WorkoutListDatabase.getDatabase(application).workoutListDao()
private val workoutListRepo = WorkoutListRepository(workoutDao)
fun setList(part : BodyPart) {
viewModelScope.launch(Dispatchers.IO) {
workoutListRepo.getWorkoutList()
}
}
}
----------------------------------------------------------------------------------------------
DB에 초기데이터가 생기는 경우입니다.
1. insertWorkoutList(data)만 호출되었을 경우
-DB 생성도 없고 테이블 생성도 없음.

2.getWokroutList() 만 호출 되었을 경우
- DB 및 테이블 생성됨, 하지만 초기 데이터 저장 안됨


3. 둘다 호출 되었을 경우.
- 모두 정상적으로 생성되고 저장 됨.

저는 ViewModel에서 WorkoutListDatabase.getDatabase()가 실행되는 순간 DB가 생성되고
Callback 클래스의 insertWorkoutList()에 의해 초기 데이터가 저장되는 것을 기대했는데요,
우연히 그렇지 않다는 것을 발견하고 주석처리해가면서 확인해보니 insertWorkoutLIst()와 getWorkoutList()가 모두 호출될때
저장되는것을 확인했습니다. 왜 getWorkoutList()까지 호출되어야 저장이 되는걸까요?