数据库从sqlite迁移到房间预期的表处理

时间:2019-12-07 20:36:07

标签: java android android-room

我不断收到此错误,但我仍然不知道如何解决。请帮我在这里。这是我的错误日志:

java.lang.RuntimeException: Exception while computing database live data.

 Caused by: java.lang.IllegalStateException: Migration didn't properly handle: task(com.examples.TaskEntry).

 Expected:
    TableInfo{name='task', columns={description=Column{name='description', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, priority=Column{name='priority', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, updated_at=Column{name='updated_at', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}


Found:
    TableInfo{name='task', columns={}, foreignKeys=[], indices=[]}

下面是我的TaskEntry实体类,我认为所有问题都来自于:

@Entity(tableName = "task")
public class TaskEntry {

    @PrimaryKey(autoGenerate = true)
    private int id;

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

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

    @ColumnInfo(name = "updated_at")
    private Date updatedAt;

    @Ignore
    public TaskEntry(@NonNull String description, int priority, Date updatedAt) {
        this.description = description;
        this.priority = priority;
        this.updatedAt = updatedAt;
    }

    public TaskEntry(int id, @NonNull String description, int priority, Date updatedAt) {
        this.id = id;
        this.description = description;
        this.priority = priority;
        this.updatedAt = updatedAt;
    }

在此代码中,我设法将“迁移”实例调用到“会议室数据库类”:

final static Migration MIGRATION_5_6 = new Migration(5, 6) {
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
        // Since we didn't alter the table, there's nothing else to do here.


    }
};

public static AppDatabase getInstance(Context context) {
    if (sInstance == null) {
        synchronized (LOCK) {
            Log.d(LOG_TAG, "Creating new database instance");
            sInstance = Room.databaseBuilder(context.getApplicationContext(),
                    AppDatabase.class, AppDatabase.DATABASE_NAME)
                    .addMigrations(MIGRATION_5_6)
                    .addCallback(roomCallback)


                    .build();
        }
    }
    Log.d(LOG_TAG, "Getting the database instance");

1 个答案:

答案 0 :(得分:0)

简而言之,Room找到了一个没有 task 表的数据库,因此没有列,外键或索引。

  

下面是我的TaskEntry实体类,我认为所有问题都来自于:

我相信,如果数据库中的表名不是 task ,这将只是一个问题,例如如果表被命名为任务,并且使用@Entity(tableName = "task")代替@Entity(tableName =“ tasks”)`

否则,问题可能出在迁移中。也许通过说 /,因为我们没有更改表,所以这里无事可做。实际发生的是您正在引入表(否则,如果不添加或引入表,为什么会那样做?进行迁移)。如果是这种情况,那么迁移应该是:-

final static Migration MIGRATION_5_6 = new Migration(5, 6) {
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
        // Since we didn't alter the table, there's nothing else to do here.
        _db.execSQL("CREATE TABLE IF NOT EXISTS `task` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `description` TEXT NOT NULL, `priority` INTEGER NOT NULL, `updated_at` TEXT)");
    }
};
  • 请注意,在编译(但未运行App)后,已从生成的Java中的 AppDatabase_Impl.java 中的 createAllTables 方法复制了SQL。

但是,您可能会收到一个错误:-

error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.

因此,您需要将 updateAt 列更改为 String 类型,或者编写并实现TypeConverter。