0. 프롤로그(TMI)
1. 앱을 삭제했는데 데이터가 남아 있다구요?
2. Room cannot verify the data integrity.
2-1. 난 기존 데이터 따위는 날아가도 상관없다.
2-2. 안 돼!!! 데이터 날아가면 안 돼!!!
2-3. 중복된 이름을 사용하는 경우
0. 프롤로그(TMI)
@Dao
interface TodoDao {
@Query("SELECT * FROM Todo")
fun getAll(): List<Todo>
...
}
기존에 내가 앱에서 사용하면 Dao는 이렇게 List를 저장하고 불러오는 형식이었다.
근데 이번에 LiveData에 대해 배우면서 전면 수정하려고 하는데
@Dao
interface TodoDao {
@Query("SELECT * FROM Todo")
fun getAll(): LiveData<List<Todo>>
...
}
만약 내가 LiveData로 기존의 데이터를 감싸면..?
내가 DB 테이블을 수정한 것처럼 되려나..?
그러면 version을 증가시키거나 migration을 해야 하나??
그러면 기존 사용자들이 가지고 있던 데이터는 어떻게 하지 날아가면 안 되는데..
이런 고민들을 했는데 결론은 테이블에 저장되는 건 그대로 List이고 불러오고 나서 LiveData로 감싸주는 거라서 아무 지장이 없다.
암튼 이걸 알아보기 위해서 이것저것 하다가 삽질을 엄청 했는데
새로 알게 된 사실이 있어서 기록하려 한다.
1. 앱을 삭제했는데 데이터가 남아 있다구요?
...
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
...
Manifests 파일의 일부분이다.
여기서 allowBackup의 디폴트 값이 true로 되어있을 텐데 이게 진짜 어이없고 이해가 안 가는 부분이다.
이게 true로 되어있으면 앱을 삭제하거나 설정에 들어가서 데이터/캐시 지우기해도 데이터베이스가 살아있다.
안드로이드 6.0부터는 앱을 삭제해도 구글 드라이브에 데이터베이스를 백업해둔다고 한다.
나는 그것도 모르고 계속 DB가 꼬이고 쌓이고 난리 부르스를 쳐서.. 하...
공식문서에서 이 사실을 확인할 수 있다.
2. Room cannot verify the data integrity.
Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number.
이 에러가 계속 떠서 미쳐버리는 줄 알았다.
데이터의 무결성을 위반해서 뜨는 에러인데 버전을 올려서 해결하라고 나와있다.
좀 더 쉽게 표현하면 이런 것이다.
"엥? 야 너 이 이름으로 데이터베이스 이미 만들었잖아. 테이블 내용을 바꾸려고?"
"그러면 버전 올려~ 간단하게 해결할 수 있어"
여기서 저 말에 현혹되지 말고 상황에 맞게 해결해야 한다.
2-1. 난 기존 데이터 따위는 날아가도 상관없다.
var db = Room.databaseBuilder(
application,
TestDatabase::class.java, "database-test"
)
.fallbackToDestructiveMigration() // 기존 데이터를 버리고 다음 버전으로 넘어감
.build()
build 할 때 fallbackToDestructiveMigration()를 호출해서 기존 데이터를 버리고
@Database(entities = [Test::class], version = 1, exportSchema = false)
abstract class TestDatabase: RoomDatabase() {
abstract fun testDao(): TestDao
}
버전을 올려주면 된다. 예를 들어 위의 코드 경우 version이 1로 되어있으니 2로 바꾸어주면 된다.
2-2. 안 돼!!! 데이터 날아가면 안 돼!!!
이미 출시한 앱의 경우 사용자들이 저장해둔 데이터가 삭제되면 안 되니 migration을 해야 한다.
이 경우 [목차 2-1]에서 설명한 fallbackToDestructiveMigration을 절대절대절대절대 쓰면 안 된다.
나는 여기에 해당되지 않아서 방법만 찾아보고 시도를 해보지 않았기 때문에 잘 설명되어 있는 링크만 몇 개 첨부하려고 한다.
2-3. 중복된 이름을 사용하는 경우
var db = Room.databaseBuilder(
application,
TestDatabase::class.java, "database-test" // 이름 중복 확인
)
.build()
혹시 앱에서 데이터베이스를 쓰는 곳이 여러 군데라면 이름이 중복되진 않는지 확인해보자
나는 기존 코드를 복붙 하는 과정에서 이름 바꾸는 걸 까먹어서 계속 이 에러가 떴다. 진짜 멍청...
💡 느낀 점
- 굳이 앱의 데이터를 구글 드라이브에 백업하는 이유는 무엇일까? 심지어 디폴트 값도 true이다.
- 이것 때문에 보안 취약 점이 생긴다고 하니 꼭 필요한 게 아니라면 항상 false로 바꿔야겠다.
- Room에 대해 설명하는 블로그는 많아도 migration까지 다루는 블로그는 많지 않다. 공부해서 올려야겠다.
- 어이없는 실수로 반나절을 날렸더니 현타가...
'오늘은 뭘 배울까? > Android' 카테고리의 다른 글
Retrofit이란? (사용하기 전에 알아야 할 것들) (10) | 2021.04.02 |
---|---|
Retrofit으로 html response 얻기 (webView 사용 아님) (2) | 2021.03.16 |
RecyclerView + MVVM + Room을 연습해보자! (0) | 2021.03.11 |
안드로이드 View Model(뷰 모델)을 공부해보자! (14) | 2021.03.08 |
안드로이드 Clean Architecture (2) | 2021.03.07 |
댓글