我知道有关此问题的一些帖子。但我无法弄清楚。我有一个现有的SQLite数据库。我正在尝试将此数据库迁移到Room。在运行时出现此错误:
Caused by: java.lang.IllegalStateException: Migration didn't properly handle: offerings(test.db.OfferingEntity).
Expected:
TableInfo{name='offerings', columns={date=Column{name='date', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, freewill=Column{name='freewill', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, offered=Column{name='offered', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, thanksgiving=Column{name='thanksgiving', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, _id=Column{name='_id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, heave=Column{name='heave', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, type=Column{name='type', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, experience=Column{name='experience', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, favorite=Column{name='favorite', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, verses=Column{name='verses', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, wave=Column{name='wave', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, vow=Column{name='vow', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
Found:
TableInfo{name='offerings', columns={date=Column{name='date', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, freewill=Column{name='freewill', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, offered=Column{name='offered', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, thanksgiving=Column{name='thanksgiving', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, _id=Column{name='_id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, heave=Column{name='heave', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, experience=Column{name='experience', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, type=Column{name='type', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, favorite=Column{name='favorite', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, verses=Column{name='verses', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, wave=Column{name='wave', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, vow=Column{name='vow', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
区别在于
freewill=Column{name='freewill', type='INTEGER', affinity='3', notNull=true, ...}
和
freewill=Column{name='freewill', type='INTEGER', affinity='3', notNull=false, ...}
列freewill
显然需要notNull=true
。这是我尝试过的:
1)在我的实体中,我使用了@NonNull
批注:
@ColumnInfo(name = FREEWILL)
@NonNull
private int freewill = 0;
此处,错误消息未更改:发生相同的IllegalStateException。
2)在迁移中,我使用了:
database.execSQL("ALTER TABLE " + OfferingEntity.TABLE_NAME + " ADD COLUMN " + OfferingEntity.FREEWILL + " INTEGER NOT NULL DEFAULT 0");
在这里,我收到以下错误消息:
java.lang.RuntimeException: Exception while computing database live data.
Caused by: android.database.sqlite.SQLiteException: duplicate column name: freewill (code 1 SQLITE_ERROR): , while compiling: ALTER TABLE offerings ADD COLUMN freewill INTEGER NOT NULL DEFAULT 0
当然,此列已存在,并且我的代码再次添加了同一列。因此错误。
这是我的数据库类:
@Database(entities = {OfferingEntity.class}, version = 6, exportSchema = false)
public abstract class OfferingsDatabase extends RoomDatabase {
private static final Object LOCK = new Object();
private static OfferingsDatabase INSTANCE;
public static OfferingsDatabase getInstance(Context context) {
if(INSTANCE == null) {
synchronized (LOCK){
INSTANCE = Room.databaseBuilder(context.getApplicationContext(), OfferingsDatabase.class, DbUtil.DB_NAME)
.addMigrations(MIGRATION_5_6)
.build();
}
}
return INSTANCE;
}
public abstract OfferingsDao offeringsDao();
static final Migration MIGRATION_5_6 = new Migration(5, 6) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE " + OfferingEntity.TABLE_NAME + " ADD COLUMN " + OfferingEntity.FREEWILL + " INTEGER NOT NULL DEFAULT 0");
}
};
}
在此实体:
@Entity(tableName = OfferingEntity.TABLE_NAME)
public class OfferingEntity {
static final String TABLE_NAME = "offerings";
static final String ID = "_id";
static final String FREEWILL = "freewill";
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = ID)
private int id;
@ColumnInfo(name = FREEWILL)
@NonNull
private int freewill = 0;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getFreewill() {
return freewill;
}
public void setFreewill(@NonNull int freewill) {
this.freewill = freewill;
}
}
有人对此有解决方案吗?
答案 0 :(得分:0)
我知道了。我不得不将int
更改为Integer
。然后它按预期工作。