Android房间迁移null错误
Posted
技术标签:
【中文标题】Android房间迁移null错误【英文标题】:Android room migration null error 【发布时间】:2018-05-13 17:10:09 【问题描述】:当我在 android 上从旧的 sqlite 方式迁移到 Room 时,我需要使用“INTEGER NOT NULL”进行编译。 问题是,当迁移发生时,您正在使用“NOT NULL”参数在新表中插入 NULL 字段,我收到错误
android.database.sqlite.SQLiteConstraintException:NOT NULL 约束失败:note.notification_state(代码 1299)
编辑:
11-29 22:52:58.891 14605-14630/com.aleksandarvasilevski.notes E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1
Process: com.aleksandarvasilevski.notes, PID: 14605
java.lang.IllegalStateException: Migration didn't properly handle note(com.aleksandarvasilevski.notes.repository.db.Note).
Expected:
TableInfoname='note', columns=notification_date=Columnname='notification_date', type='TEXT', notNull=false, primaryKeyPosition=0, priority=Columnname='priority', type='INTEGER', notNull=true, primaryKeyPosition=0, description=Columnname='description', type='TEXT', notNull=false, primaryKeyPosition=0, title=Columnname='title', type='TEXT', notNull=false, primaryKeyPosition=0, id=Columnname='id', type='INTEGER', notNull=true, primaryKeyPosition=1, notification_state=Columnname='notification_state', type='INTEGER', notNull=true, primaryKeyPosition=0, created_date=Columnname='created_date', type='TEXT', notNull=false, primaryKeyPosition=0, foreignKeys=[], indices=[]
Found:
TableInfoname='note', columns=notification_date=Columnname='notification_date', type='TEXT', notNull=false, primaryKeyPosition=0, priority=Columnname='priority', type='INTEGER', notNull=false, primaryKeyPosition=0, title=Columnname='title', type='TEXT', notNull=false, primaryKeyPosition=0, description=Columnname='description', type='TEXT', notNull=false, primaryKeyPosition=0, id=Columnname='id', type='INTEGER', notNull=true, primaryKeyPosition=1, notification_state=Columnname='notification_state', type='INTEGER', notNull=false, primaryKeyPosition=0, created_date=Columnname='created_date', type='TEXT', notNull=false, primaryKeyPosition=0, foreignKeys=[], indices=[]
at com.aleksandarvasilevski.notes.repository.db.NoteDatabase_Impl$1.validateMigration(NoteDatabase_Impl.java:70)
at android.arch.persistence.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:75)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onUpgrade(FrameworkSQLiteOpenHelper.java:118)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:256)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:93)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:54)
at android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:193)
at com.aleksandarvasilevski.notes.repository.db.NoteDao_Impl$5.compute(NoteDao_Impl.java:195)
at com.aleksandarvasilevski.notes.repository.db.NoteDao_Impl$5.compute(NoteDao_Impl.java:181)
at android.arch.lifecycle.ComputableLiveData$2.run(ComputableLiveData.java:87)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
代码:
`@Database(entities = Note.class, 版本 = 3) 公共抽象类 NoteDatabase 扩展 RoomDatabase
public static final Migration MIGRATION_2_3 = new Migration(2, 3)
@Override
public void migrate(@NonNull SupportSQLiteDatabase database)
database.execSQL(
"CREATE TABLE note (id INTEGER NOT NULL, title TEXT, description TEXT, created_date TEXT, notification_date TEXT, notification_state INTEGER, priority INTEGER, PRIMARY KEY(id))");
database.execSQL(
"INSERT INTO note (id, title, description, created_date) SELECT _ID, title, description, date FROM notes");
;`
【问题讨论】:
如果您想要INTEGER NOT NULL
,您将无法在该列中存储null
值。这不是特定于房间的。如果您现有的数据库允许该列的 null
值,请不要将其设为 NOT NULL
或弄清楚您要对现有的 null
值进行哪种转换。
问题是整数不能为空,否则编译时出错。
请编辑您的问题并发布minimal reproducible example,显示您的编译时错误和产生错误的代码。
【参考方案1】:
好的,我知道了,如果有人遇到同样的问题,请使用 NOT NULL DEFAULT 0(或其他数字)。
@Database(entities = Note.class, version = 3)
public abstract class NoteDatabase extends RoomDatabase
public static final Migration MIGRATION_2_3 = new Migration(2, 3)
@Override
public void migrate(@NonNull SupportSQLiteDatabase database)
database.execSQL(
"CREATE TABLE note (id INTEGER NOT NULL, " +
"title TEXT, description TEXT, created_date TEXT, notification_date TEXT, " +
"notification_state INTEGER NOT NULL DEFAULT 0, " +
"priority INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(id))");
database.execSQL(
"INSERT INTO note (id, title, description, created_date) " +
"SELECT _ID, title, description, date FROM notes");
;
// ...
【讨论】:
【参考方案2】:迁移代码:
class Migration1To2: Migration(1, 2)
override fun migrate(database: SupportSQLiteDatabase)
database.execSQL("ALTER TABLE 'table_name' ADD COLUMN 'row_to modify' INTEGER NOT NULL **DEFAULT 1"**)
Dao Entity add **defaultValue = "1"**:
@ColumnInfo( name="row_to modify", defaultValue = "1")
var row_to modify: Int
【讨论】:
This 似乎是 Google Developers 文档。但是.. 你为什么选择 Kotlin?以上是关于Android房间迁移null错误的主要内容,如果未能解决你的问题,请参考以下文章