'Android Room Migration didn't properly handle
Through crashlytics I'm finding a crash event saying room did not handle the migration of one of my tables. Can anyone see what exactly could be wrong with my table? As far as i'm aware it's correct in terms of adding default values, and i've even done auto migrations with way previously without issues
Fatal Exception: java.lang.IllegalStateException: Migration didn't properly handle: player_table(com.tapmax.football.model.PlayerModel).
Expected:
TableInfo{name='player_table', columns={skillMoves=Column{name='skillMoves', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}, playerName=Column{name='playerName', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, pace=Column{name='pace', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}, shooting=Column{name='shooting', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}, defending=Column{name='defending', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}, playerImageUrl=Column{name='playerImageUrl', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, dribbling=Column{name='dribbling', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}, overall=Column{name='overall', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}, passing=Column{name='passing', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}, playerPosition=Column{name='playerPosition', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}, value=Column{name='value', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}, physic=Column{name='physic', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}, playerNameUnaccented=Column{name='playerNameUnaccented', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, age=Column{name='age', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}, playerId=Column{name='playerId', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1, defaultValue='null'}, playerPositionCategory=Column{name='playerPositionCategory', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultVal<truncated: 627 chars>
at androidx.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:103)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onUpgrade(FrameworkSQLiteOpenHelper.java:183)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:489)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:387)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:151)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:112)
at androidx.room.RoomDatabase.inTransaction(RoomDatabase.java:706)
at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.java:483)
at com.tapmax.football.database.dao.DraftTeamDao_Impl.getDraftTeam(DraftTeamDao_Impl.java:110)
at com.tapmax.football.viewmodel.BuildScreenViewModel$1.invokeSuspend(BuildScreenViewModel.kt:67)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:39)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
Table: the fields from 'playerPosition' and down are the new fields i've added. I put an auto migration strategy in my database for these.
@Serializable
@Entity(tableName = "player_table")
data class PlayerModel(
@PrimaryKey
var playerId: String = "",
var playerName: String = "",
var playerNameUnaccented: String = "",
var playerImageUrl: String = "https://cdn.sofifa.com/players/notfound_0_120.png",
@ColumnInfo(defaultValue = "")
var playerPosition: String = "",
@ColumnInfo(defaultValue = "")
var playerPositionCategory: String = "",
@ColumnInfo(defaultValue = "")
var overall: String = "",
@ColumnInfo(defaultValue = "")
var value: String = "",
@ColumnInfo(defaultValue = "")
var age: String = "",
@ColumnInfo(defaultValue = "")
var skillMoves: String = "",
@ColumnInfo(defaultValue = "")
var pace: String = "",
@ColumnInfo(defaultValue = "")
var shooting: String = "",
@ColumnInfo(defaultValue = "")
var passing: String = "",
@ColumnInfo(defaultValue = "")
var dribbling: String = "",
@ColumnInfo(defaultValue = "")
var defending: String = "",
@ColumnInfo(defaultValue = "")
var physic: String = ""
)
Database
@Database(
entities =
[
PlayerModel::class,
SavedTeam::class,
DraftTeam::class,
Design::class
],
version = 2,
exportSchema = true,
autoMigrations = [AutoMigration(from = 1, to = 2)]
)
@TypeConverters(
BuildScreenStateConverter::class
)
abstract class LocalDatabase : RoomDatabase() {
abstract fun playerDao(): PlayerDao
abstract fun savedTeamDao(): SavedTeamDao
abstract fun draftTeamDao(): DraftTeamDao
abstract fun designDao(): DesignDao
companion object {
@Volatile
private var INSTANCE: LocalDatabase? = null
fun getDatabase(context: Context): LocalDatabase {
val tempInstance = INSTANCE
if (tempInstance != null) {
return tempInstance
}
synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
LocalDatabase::class.java,
"local_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
return instance
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
