I am developing an android application and in my app i have implemented Room Database. My app is already live on playstore as now i am trying to send an update to app where there are changes in schema. I have added new column, its type is string and it should be NOT NULL so i will be providing a default value with it.
I have written a migration query for that, but app always crashes.
Question: Why in expected the modifyDate column notNull=false but i want it to be NOT NULL. I don't see any difference in Expected and Found part expect the notNull status and value
I am unable to find the actual cause of this crash.
Below is my code:
Entity Class
@Keep
@Entity
class PdfFile() {
//Columns before migration
@PrimaryKey(autoGenerate = true)
private var mid = 0
private var mFile_name: String? = null
private var mFile_size = "0mb"
private var mFileDate = "17-06-2020"
private var mParent_file = ""
private var mAbsolute_path: String? = null
private var fileType = ""
private var isViewed = false
private var isBookmarked = false
//TEST MIGRATION
@ColumnInfo(name = "modifyDate")
private var modifyDate = ""
fun setMid(mid: Int) {
this.mid = mid
}
fun getMid(): Int {
return mid
}
fun getMFile_name(): String? {
return mFile_name
}
fun getMFile_size(): String {
return mFile_size
}
fun getMFileDate(): String {
return mFileDate
}
fun getMParent_file(): String {
return mParent_file
}
fun getMAbsolute_path(): String? {
return mAbsolute_path
}
fun getFileType(): String {
return fileType
}
fun getIsViewed(): Boolean {
return isViewed
}
fun getIsBookmarked(): Boolean {
return isBookmarked
}
fun getModifyDate(): String {
return modifyDate
}
fun setMFile_name(name: String) {
this.mFile_name = name
}
fun setMFile_size(size: String) {
this.mFile_size = size
}
fun setMFileDate(date: String) {
this.mFileDate = date
}
fun setMParent_file(parentFile: String) {
this.mParent_file = parentFile
}
fun setMAbsolute_path(path: String) {
this.mAbsolute_path = path
}
fun setFileType(fileType: String) {
this.fileType = fileType
}
fun setIsViewed(isView: Boolean) {
this.isViewed = isView
}
fun setIsBookmarked(isBookmark: Boolean) {
this.isBookmarked = isBookmark
}
fun setModifyDate(date: String) {
this.modifyDate = date
}
override fun equals(obj: Any?): Boolean {
return if (obj !is PdfFile) {
false
} else {
val PdfFile = obj as PdfFile
mFile_name == PdfFile.getMFile_name()
&& mAbsolute_path == PdfFile.getMAbsolute_path()
&& mFile_size == PdfFile.getMFile_size()
}
}
}
Room Database Class
//Please note the previous version was 1 now i have changed to 2 after adding a new column to entity
@Database(
entities = [PdfFile::class],
version = 2,
exportSchema = false
)
abstract class RoomDbData : RoomDatabase() {
abstract fun taskDao(): DataDao
}
DatabaseManager Class
const val DATABASE_NAME = “MyDb”
class DatabaseManager(context: Context) {
//Migrating from version 1 to version 2
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE PdfFile ADD COLUMN modifyDate TEXT NOT NULL DEFAULT '' ")
}
}
val appDatabase: RoomDbData
init {
appDatabase =
Room.databaseBuilder(context, RoomDbData::class.java, DATABASE_NAME)
.allowMainThreadQueries()
.addMigrations(MIGRATION_1_2)
.build()
}
}
EXCEPTION
Process: mypackagename, PID: 10993
java.lang.RuntimeException: Exception while computing database live data.
at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:92)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.IllegalStateException: Migration didn't properly handle: PdfFile(mypackagename.models.entities.PdfFile).
Expected:
TableInfo{name='PdfFile', columns={isBookmarked=Column{name='isBookmarked', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, modifyDate=Column{name='modifyDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, mFile_size=Column{name='mFile_size', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, mid=Column{name='mid', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, mFileDate=Column{name='mFileDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, mAbsolute_path=Column{name='mAbsolute_path', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, mParent_file=Column{name='mParent_file', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, mFile_name=Column{name='mFile_name', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, fileType=Column{name='fileType', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, isViewed=Column{name='isViewed', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
Found:
TableInfo{name='PdfFile', columns={isBookmarked=Column{name='isBookmarked', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, modifyDate=Column{name='modifyDate', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}, mFile_size=Column{name='mFile_size', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, mid=Column{name='mid', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, mFileDate=Column{name='mFileDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, mAbsolute_path=Column{name='mAbsolute_path', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, mParent_file=Column{name='mParent_file', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, mFile_name=Column{name='mFile_name', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, fileType=Column{name='fileType', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, isViewed=Column{name='isViewed', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
at androidx.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:103)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onUpgrade(FrameworkSQLiteOpenHelper.java:124)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:299)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:194)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:92)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:53)
at androidx.room.RoomDatabase.inTransaction(RoomDatabase.java:476)
at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.java:281)
2020-10-20 15:14:41.031 10993-11039/mypackagename E/AndroidRuntime: at androidx.room.RoomDatabase.query(RoomDatabase.java:324)
at androidx.room.util.DBUtil.query(DBUtil.java:83)
at mypackagename.models.dao.DataDao_Impl$13.call(DataDao_Impl.java:325)
at mypackagename.models.dao.DataDao_Impl$13.call(DataDao_Impl.java:322)
at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:90)
... 3 more
2020-10-20 15:14:41.064 1764-1833/? E/InputDispatcher: channel 'f088a5d mypackagename/mypackagename.views.activities.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
2020-10-20 15:14:41.067 1764-1833/? E/InputDispatcher: channel '1aca3d4 mypackagename/mypackagename.views.activities.SplashActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
2020-10-20 15:14:41.110 1764-4588/? E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008cdf
2020-10-20 15:14:41.111 1764-4588/? E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008cdf
2020-10-20 15:14:41.111 1764-4588/? E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008824
2020-10-20 15:14:41.111 1764-4588/? E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008824
2020-10-20 15:14:41.233 1541-4743/? E/AudioFlinger: not enough memory for AudioTrack size=131296
2020-10-20 15:14:41.233 1541-4743/? E/AudioFlinger: createRecordTrack_l() initCheck failed -12; no control block?
2020-10-20 15:14:41.233 2486-7131/? E/AudioRecord: AudioFlinger could not create record track, status: -12
2020-10-20 15:14:41.236 2486-7131/? E/AudioRecord-JNI: Error creating AudioRecord instance: initialization check failed with status -12.
2020-10-20 15:14:41.236 2486-7131/? E/android.media.AudioRecord: Error code -20 when initializing native AudioRecord object.
2020-10-20 15:14:41.237 2486-7131/? E/ActivityThread: Failed to find provider info for
PLEASE NOTE THAT I HAVEN'T MADE ANY CHANGES TO DAO FOR THIS MIGRATION. Is any changed required there too?
Can someone please help me out with this. Any help will be appreciated. Thanks
To make sure modifyDate is non-null you need to make below change:
private var modifyDate = ""
to
private var modifyDate: String = ""