After updating Android-Room version from 2.2.x to 2.4.x, I decide to use auto-migration feature to help me write less code. So I want to deprecate all migration written manually and use auto-migration instead. But I have got an error when using auto-migration:
// Compile Time Error:
// New NOT NULL column'height' added with no default value specified.
// Please specify the default value using @ColumnInfo.
@ColumnInfo(name = "height")
val height: Long = 0L
Even if I have specify default value by this way, but still get same error:
@ColumnInfo(name = "height", defaultValue = "0")
val height: Long = 0L
What wrong with my code and how can I fix this error?
I have two version database:
Version 1
@Entity(tableName = "user")
data class User(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val id: Long = 0L,
@ColumnInfo(name = "name")
val name: String = ""
)
@Database(
entities = [User::class],
version = 1
)
abstract class UserDB : RoomDatabase()
then at version 2 I add a column which name is 'height' in user table:
Version 2
@Entity(tableName = "user")
data class User(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val id: Long = 0L,
@ColumnInfo(name = "name")
val name: String = "",
@Column(name = "height")
val height: Long = 0L
)
@Database(
entities = [User::class],
version = 2
)
abstract class UserDB : RoomDatabase() {
object ManualMigrations {
val M_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE user ADD COLUMN height INTEGER NOT NULL DEFAULT 0")
}
}
}
}
Now I want to deprecate all manual migration and use auto-migration instead. I change the code and got an error:
// Compile Time Error:
// New NOT NULL column'height' added with no default value specified.
// Please specify the default value using @ColumnInfo.
@Database(
entities = [User::class],
autoMigrations = [
AutoMigration(from = 1, to = 2)
],
version = 2
)
abstract class UserDB : RoomDatabase()
even if I have specify default value by @ColumnInfo, but still got same error:
// Compile Time Error:
// New NOT NULL column'height' added with no default value specified.
// Please specify the default value using @ColumnInfo.
@Entity(tableName = "user")
data class User(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val id: Long = 0L,
@ColumnInfo(name = "name")
val name: String = "",
// specify default value by this way
@Column(name = "height", defaultValue = "0")
val height: Long = 0L
)
@Database(
entities = [User::class],
autoMigrations = [
AutoMigration(from = 1, to = 3)
],
// Since I have modify the structure of table,
// I increase the version.
version = 3
)
abstract class UserDB : RoomDatabase()
What wrong with my code and how can i fix this error?
I have modify the annotation of height field
from
@Column(name = "height", defaultValue = "0")
val height: Long = 0L
to
@ColumnInfo(name = "height", defaultValue = "0")
val height: Long = 0L
And follow above step but get a runtime exception
@ColumnInfo(name = "height") and database version update to version 2 by writing manual migration. then run new version app;@ColumnInfo(name = "height", defaultValue = "0")
(if I not specify default value, room compiler will tell me I must specify default value by throwing Exception during compile time) and increase version from 2 to 3, and specify autoMigrations into @Database:@Database(
entities = [Worker::class],
autoMigrations = [AutoMigration(from = 1, to = 3)],
version = 3
)
abstract class UserDB : RoomDatabase()
Then at runtime execute these code and got an runtime exception:
val userDB = buildUserDB().openHelper.readableDatabase
Log.d(TAG, "columnNames=${workerDB.query("SELECT * FROM user").columnNames.toList()}")
// java.lang.IllegalStateException: A migration from 2 to 3 was required but not found.
// Please provide the necessary Migration path via RoomDatabase.Builder.addMigration(Migration ...)
// or allow for destructive migrations via one of the
// RoomDatabase.Builder.fallbackToDestructiveMigration* methods.
even if I have specify default value by @ColumnInfo, but still got same error:
I believe (according to the long version) that your issue is that you are using @Column(.... instead of @ColumnInfo(.....
So change
@Column(name = "height", defaultValue = "0")
val height: Long = 0L
to
@ColumnInfo(name = "height", defaultValue = "0")
val height: Long = 0L
Testing the above using two runs one at version 1 and then 2 (using corrected @ColumnInfo) using:-
class MainActivity : AppCompatActivity() {
lateinit var db: UserDB
lateinit var dao: UserDao
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = UserDB.getInstance(this)
dao = db.getUserDao()
dao.insert(User(name = "NAME001Version$DATABASE_VERSION"))
dao.insert(User(name = "NAME002Version$DATABASE_VERSION"))
dao.insert(User(name = "NAME003Version$DATABASE_VERSION"))
for (u in dao.getAllUsers()) {
Log.d("DBINFO","User ID = ${u.id} UserName is ${u.name} Version is ${DATABASE_VERSION}")
}
}
}
The DB via App inspection is :-

The logs from both runs :-
2022-05-24 19:32:57.784 D/DBINFO: User ID = 1 UserName is NAME001Version1 Version is 1
2022-05-24 19:32:57.784 D/DBINFO: User ID = 2 UserName is NAME002Version1 Version is 1
2022-05-24 19:32:57.784 D/DBINFO: User ID = 3 UserName is NAME003Version1 Version is 1
2022-05-24 19:38:41.963 D/DBINFO: User ID = 1 UserName is NAME001Version1 Version is 2
2022-05-24 19:38:41.963 D/DBINFO: User ID = 2 UserName is NAME002Version1 Version is 2
2022-05-24 19:38:41.964 D/DBINFO: User ID = 3 UserName is NAME003Version1 Version is 2
2022-05-24 19:38:41.964 D/DBINFO: User ID = 4 UserName is NAME001Version2 Version is 2
2022-05-24 19:38:41.964 D/DBINFO: User ID = 5 UserName is NAME002Version2 Version is 2
2022-05-24 19:38:41.964 D/DBINFO: User ID = 6 UserName is NAME003Version2 Version is 2
To replicate the issue (had to add a basic annotation for @Column) and then:-

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With