android - 房间数据库迁移没有正确处理 ALTER TABLE 迁移

标签 android sqlite android-room

Java.lang.IllegalStateException

Migration didn't properly handle 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=[]}

我正在尝试执行简单的迁移,我有一个名为 User 的类,它有两列 ID (primary key)NAME TEXT 然后我用两个用户数据填充数据库,然后我在对象 User 中添加列 AGE 并在迁移常量中添加一个 alter 表 添加这个新列,最后我将数据库版本 1 替换为 2。

这里是代码

用户类

@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(entities = {User.class}, version = 2)
public abstract class RoomDatabaseImpl extends RoomDatabase {
    abstract UserDao userDao();
}

迁移代码

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");
    }
 };

它会调用

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

有人可以帮帮我吗,我真的不知道我做错了什么或者这是一个错误。

最佳答案

错误信息很难解析,但有区别:

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=[]}

Age 可以为空,但 Room 期望它不为空。

将您的迁移更改为:

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

由于这个异常解释非常难以解析,我创建了a small script这对你来说是不同的。

例子:

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

关于android - 房间数据库迁移没有正确处理 ALTER TABLE 迁移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46372036/

相关文章:

android - 如何在 Android 中实现 Google Places API?

android - 使 ExpandableListView 尊重项目边距和填充

Android数据库(SQLite)从空表返回非空游标

android - android架构组件中executor的使用

java - 如何在方法中正确发送上下文、 Activity 和接口(interface)连接?

java - Android Studio 删除 Reyclerview 和 Sqlitedb 中的所有行

android - 如何在无根的 Android 手机上使用 'drop' sqlite 数据库?

android - 依赖 SQLite 中数据的 Robotium Activity 测试

android - 分页库 - 一个具有多种 View 类型的回收器

java - 使用 Room Persistence 在运行时生成查询