10

I am making a migration using Room database. I am getting this error:

java.lang.IllegalStateException: Migration didn't properly handle coffee_productivity(io.github.omisie11.coffeeproductivitytracker.database.entity.CoffeeProductivityData).
 Expected:
TableInfo{name='coffee_productivity', columns={date=Column{name='date', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1}, productivity=Column{name='productivity', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, coffees_volume=Column{name='coffees_volume', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, number_of_coffees=Column{name='number_of_coffees', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}}, foreignKeys=[], indices=[Index{name='index_coffee_productivity_date', unique=true, columns=[date]}]}
 Found:
TableInfo{name='coffee_productivity', columns={date=Column{name='date', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0}, productivity=Column{name='productivity', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, coffees_volume=Column{name='coffees_volume', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0}, number_of_coffees=Column{name='number_of_coffees', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1}}, foreignKeys=[], indices=[Index{name='index_coffee_productivity_date', unique=true, columns=[date]}]}

It looks like order of columns changed, but the only thing I did was to add a new column. Entity:

@Entity(tableName = "coffee_productivity", indices = [Index(value = "date", unique = true)])
data class CoffeeProductivityData(
@PrimaryKey(autoGenerate = true) var id: Long?,
@ColumnInfo(name = "date") var date: String,
@ColumnInfo(name = "productivity") var productivity: Int,
@ColumnInfo(name = "number_of_coffees") var numberOfCoffees: Int,
@ColumnInfo(name = "coffees_volume") var coffeesVolume: Int)
{
constructor() : this(null, "00/00/0000", 0, 0, 0)
}

Database class:

@Database(entities = [CoffeeProductivityData::class], version = 2)
abstract class CoffeeProductivityDatabase : RoomDatabase() {

    abstract fun coffeeProductivityDao(): CoffeeProductivityDao

    companion object {
        private var dbInstance: CoffeeProductivityDatabase? = null

        private val MIGRATION_1_2: Migration = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL("ALTER TABLE 'coffee_productivity' ADD COLUMN 'coffees_volume' INTEGER DEFAULT 0")
            }
        }

        fun getDatabase(context: Context): CoffeeProductivityDatabase? {
            if (dbInstance == null) {

                dbInstance = Room.databaseBuilder<CoffeeProductivityDatabase>(
                        context.applicationContext,
                        CoffeeProductivityDatabase::class.java,"coffee_productivity.db")
                        .addMigrations(MIGRATION_1_2)
                        .build()
            }
            return dbInstance
        }
    }
}
OMIsie11
  • 459
  • 5
  • 19

3 Answers3

10

Expected:

coffees_volume=Column{name='coffees_volume', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}

Found:

coffees_volume=Column{name='coffees_volume', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0}

The problem is in your notNull attribute. Replace your model with following code:

@Entity(tableName = "coffee_productivity", indices = [Index(value = "date", unique = true)])
data class CoffeeProductivityData(
@PrimaryKey(autoGenerate = true) var id: Long?,
@ColumnInfo(name = "date") var date: String,
@ColumnInfo(name = "productivity") var productivity: Int,
@ColumnInfo(name = "number_of_coffees") var numberOfCoffees: Int,
@ColumnInfo(name = "coffees_volume") var coffeesVolume: Int? = 0)
{
   constructor() : this(null, "00/00/0000", 0, 0, 0)
}
Jitesh Prajapati
  • 2,533
  • 4
  • 29
  • 51
Sujin Shrestha
  • 1,203
  • 2
  • 13
  • 23
0

Please replace the query Like

ALTER TABLE 'coffee_productivity' ADD COLUMN 'coffees_volume' INTEGER NOT NULL DEFAULT 0
Jitesh Prajapati
  • 2,533
  • 4
  • 29
  • 51
Francis
  • 217
  • 2
  • 4
0

What happens is that you changed your table by adding fields or by removing or changing the name and time of doing the migration gave this problem, without putting the changes in the table. But he hopes that his table was in the right expectation, so he found different what he expected, I decided like this:

val MIGRATION_2_3 = object: Migration (2, 3) {
    override fun migrate (database: SupportSQLiteDatabase) {
        database.execSQL ("" "
                CREATE TABLE new_Song (
                    id INTEGER PRIMARY KEY NOT NULL,
                    name TEXT,
                    TEXT NOT NULL DEFAULT tag ''
                )
                "" ".trimIndent ())
        database.execSQL ("" "
                INSERT INTO new_Song (id, name, tag)
                SELECT id, name, tag FROM Song
                "" ".trimIndent ())
        database.execSQL ("DROP TABLE Song")
        database.execSQL ("ALTER TABLE new_Song RENAME TO Song")
    }
}

At the end of the page teaches the reason for the official website of Room: https://developer.android.com/training/data-storage/room/migrating-db-versions?hl=en#kotlin