Object database migration does not handle ALTER TABLE migration

java.lang.IllegalStateException

Migration was not handled correctly by the User (therealandroid.github.com.roomcore.java.User).

Expected:

TableInfo {name = 'user', columns = {name = Column {name = 'name', type = 'TEXT', notNull = false, primaryKeyPosition = 0}, age = Column {name = 'age', type = 'INTEGER ', notNull = true, primaryKeyPosition = 0}, id = Column {name =' id ', type =' INTEGER ', notNull = true, primaryKeyPosition = 1}}, foreignKeys = []} Found:

Found

TableInfo {name = 'user', columns = {name = Column {name = 'name', type = 'TEXT', notNull = false, primaryKeyPosition = 0}, id = Column {name = 'id', type = 'INTEGER ', notNull = true, primaryKeyPosition = 1}, age = Column {name =' age ', type =' INTEGER ', notNull = false, primaryKeyPosition = 0}}, foreignKeys = []}

I am trying to do a simple migration, I have a class called User, and it has two columns ID (primary key)and NAME TEXT, and then I populate the database with two user data, then I add a column AGEin the object Userand in the transfer constant I add alter tableto add this new column and finally I am replacing the database version from 1 to 2.

Here is the code

User.class

@Entity(tableName = "user")
  public class User {

  @PrimaryKey
  private int id;

  @ColumnInfo(name = "name")
  private String name;

  @ColumnInfo(name = "age")
  private int age;


  public int getId() {
      return id;
  }

  public void setId(int id) {
      this.id = id;
  }

  public String getName() {
      return name;
  }

  public void setName(String name) {
      this.name = name;
  }

  public int getAge() {
      return age;
  }

  public void setAge(int age) {
      this.age = age;
  }
}

Database class

@Database(entities = {User.class}, version = 2)
public abstract class RoomDatabaseImpl extends RoomDatabase {
    abstract UserDao userDao();
}

Migration code

public static Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        database.execSQL("ALTER TABLE 'user' ADD COLUMN 'age' INTEGER");
    }
 };

and he calls

Room.databaseBuilder(context, RoomDatabaseImpl.class, "Sample.db")
            .addMigrations(MIGRATION_1_2)
            .allowMainThreadQueries()
            .build();

AGE .

:

  User user = new User();
  user.setName("JoooJ");
  user.setId(3);
  user.setAge(18);

  List<User> userList = new ArrayList<>();
  userList.add(user);
  App.database(this).userDao().insertAll(userList);  // The crash happens here

:

Android Studio 3, .

:

compile "android.arch.persistence.room:runtime:1.0.0-alpha9-1"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha9-1"

compile "android.arch.persistence.room:rxjava2:1.0.0-alpha9-1"
gradle 2.3.3

- , , .

+16
5

, :

TableInfo {name = 'user', columns = {name = Column {name = 'name', type = 'TEXT', notNull = false, primaryKeyPosition = 0}, age = Column {name = 'age', type = 'INTEGER ', notNull = true, primaryKeyPosition = 0}, id = Column {name =' id ', type =' INTEGER ', notNull = true, primaryKeyPosition = 1}}, foreignKeys = []} :

TableInfo {name = 'user', columns = {name = Column {name = 'name', type = 'TEXT', notNull = false, primaryKeyPosition = 0}, id = Column {name = 'id', type = 'INTEGER ', notNull = true, primaryKeyPosition = 1}, age = Column {name =' age ', type =' INTEGER ', notNull = false, primaryKeyPosition = 0}}, foreignKeys = []}

, Room , .

:

database.execSQL("ALTER TABLE 'user' ADD COLUMN 'age' INTEGER NOT NULL");

, , diff .

:

mig "java.lang.IllegalStateException: Migration failed. expected:TableInfo{name='user', columns={name=Column{name='name', type='TEXT', notNull=false, primaryKeyPosition=0}, age=Column{name='age', type='INTEGER', notNull=true, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', notNull=true, primaryKeyPosition=1}}, foreignKeys=[]} , found:TableInfo{name='user', columns={name=Column{name='name', type='TEXT', notNull=false, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', notNull=true, primaryKeyPosition=1}, age=Column{name='age', type='INTEGER', notNull=false, primaryKeyPosition=0}}, foreignKeys=[]}"

:

expected / found diff

+30

JS-, https://hrankit.imtqy.com/RoomSQLiteDifferenceFinder/

.

  1. , .

  2. Found Found, .

  3. Go. . JSON.

  4. , , .

Android Studio Logcat.

+4

notNull, @NonNull sql ALTER TABLE. , : TYPE = TEXT, TYPE = '' (COLLATE NOCASE) INTEGER, INT, - . Sqlite .

json app\schemas, sql .

static final Migration MIGRATION_2_3= new Migration(2, 3) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {

            database.execSQL("DROP TABLE IF EXISTS table_tmp");

            database.execSQL("CREATE TABLE IF NOT EXISTS 'table_tmp' ...");

            database.execSQL("insert into table_tmp ('id', 'name' , ...");

            database.execSQL("DROP INDEX IF EXISTS 'index_table_name'");

            database.execSQL("CREATE INDEX IF NOT EXISTS 'index_table_name' ON 'table_tmp' ('name')");

            database.execSQL("DROP TABLE IF EXISTS table");

            database.execSQL("alter table table_tmp rename to table");

        }
    };
0

None of the answers are correct in any of the links. After much experimentation, I found a way to do this. The ALTER query must be written as follows in order for it to work:

database.execSQL("ALTER TABLE 'user' ADD COLUMN 'age' INTEGER NOT NULL DEFAULT 0")

However, the value of Integer DEFAULT can be any.

If you want to add a column of type String, add it as follows:

database.execSQL("ALTER TABLE 'user' ADD COLUMN 'address' TEXT")

It works like a charm.

0
source

I ran into this problem today, I just changed the fields intto Integerin Entities. Because intit cannot be null, but objects Integercan be null.

0
source

Source: https://habr.com/ru/post/1686247/


All Articles