dio*_*jme 26 sqlite android android-room
Java.lang.IllegalStateException
迁移没有正确处理用户(therealandroid.github.com.roomcore.java.User).
预期:
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 = []}
我正在尝试执行一个简单的迁移,我有一个被调用的类User,它有两列ID (primary key),NAME TEXT然后我用两个用户数据填充数据库,然后我AGE在对象中添加列,User并在迁移常量我添加一个alter table来添加这个新列,最后我将数据库1的版本替换为2.
这是代码
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;
}
}
Run Code Online (Sandbox Code Playgroud)
数据库类
@Database(entities = {User.class}, version = 2)
public abstract class RoomDatabaseImpl extends RoomDatabase {
abstract UserDao userDao();
}
Run Code Online (Sandbox Code Playgroud)
迁移代码
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");
}
};
Run Code Online (Sandbox Code Playgroud)
它打电话
Room.databaseBuilder(context, RoomDatabaseImpl.class, "Sample.db")
.addMigrations(MIGRATION_1_2)
.allowMainThreadQueries()
.build();
Run Code Online (Sandbox Code Playgroud)
在更改对象添加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
Run Code Online (Sandbox Code Playgroud)
其他信息:
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
Run Code Online (Sandbox Code Playgroud)
有人可以帮助我,我真的不知道我做错了什么或者它是一个错误.
Ben*_*fez 49
错误消息很难解析,但有一点不同:
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 = []}
年龄可以为空,但是房间预计它不会为空.
将您的迁移更改为:
database.execSQL("ALTER TABLE 'user' ADD COLUMN 'age' INTEGER NOT NULL");
Run Code Online (Sandbox Code Playgroud)
由于此异常解释非常难以解析,因此我创建了一个为您执行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=[]}"
Run Code Online (Sandbox Code Playgroud)
结果:
小智 12
我也写了一个小的JS脚本,你可以找到https://hrankit.github.io/RoomSQLiteDifferenceFinder/
这个过程非常简单.
在Expected列中输入预期的错误日志,即Left One.
在Found列中输入Found错误日志,这是正确的.
按Go.按钮.错误日志将转换为JSON.
按比较按钮和Voila,您将获得所需的差异.
此插件发现Android Studio Logcat中两个Expected和Found转储的差异.
在这里查看比较图像

在任何链接中,没有答案是正确的。经过大量实验,找到了解决之道。为了使它工作,需要以下列方式编写ALTER查询:
database.execSQL("ALTER TABLE 'user' ADD COLUMN 'age' INTEGER NOT NULL DEFAULT 0")
Run Code Online (Sandbox Code Playgroud)
但是,整数DEFAULT值可以是任何值。
如果要添加“字符串类型”列,请按以下方式添加:
database.execSQL("ALTER TABLE 'user' ADD COLUMN 'address' TEXT")
Run Code Online (Sandbox Code Playgroud)
这就像一个魅力。
如果要添加Integer类型列,请添加此代码
database.execSQL("ALTER TABLE users"
+ " ADD COLUMN year INTEGER NOT NULL DEFAULT 0 ")
Run Code Online (Sandbox Code Playgroud)