预打包的数据库有一个无效的模式 Room

Pre-packaged database has an invalid schema Room

我正在尝试加载准备好的数据库,但出现错误。我得出的结论是,由于 Room 发现了 Scored 和 CityId 两列之间的差异。 Room 期望它们是非零的,但在 Student class 中它们已经是非零的,就像在准备好的模式中一样。

需要为此架构更改哪些编辑?

java.lang.IllegalStateException: Pre-packaged database has an invalid schema: TABLE_STUDENT(com.aplication.myuniversity.pojo.Student).
 Expected:
TableInfo{name='TABLE_STUDENT', columns={CityId=Column{name='CityId', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, Scores=Column{name='Scores', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, _id=Column{name='_id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, Login=Column{name='Login', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Surname=Column{name='Surname', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Uri=Column{name='Uri', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Name=Column{name='Name', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Password=Column{name='Password', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[Index{name='index_TABLE_STUDENT__id', unique=true, columns=[_id]}]}
 Found:
TableInfo{name='TABLE_STUDENT', columns={CityId=Column{name='CityId', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Scores=Column{name='Scores', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, _id=Column{name='_id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, Login=Column{name='Login', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Surname=Column{name='Surname', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Uri=Column{name='Uri', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Name=Column{name='Name', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, Password=Column{name='Password', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[Index{name='index_TABLE_STUDENT__id', unique=true, columns=[_id]}]}

架构

CREATE TABLE "TABLE_STUDENT" (
    "_id"   INTEGER NOT NULL UNIQUE,
    "Name"  TEXT,
    "Surname"   TEXT,
    "Login" TEXT,
    "Password"  TEXT,
    "Uri"   TEXT,
    "CityId"    INTEGER,
    "Scores"    INTEGER,
    PRIMARY KEY("_id")
);

Java

public class Student {
        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(name = BaseColumns._ID)
        protected int id;
        @ColumnInfo(name = StudentEntry.NAME)
        private String name; // name
        @ColumnInfo(name = StudentEntry.SURNAME)
        private String surname;  // surname
        @ColumnInfo(name = StudentEntry.LOGIN)
        private String login;
        @ColumnInfo(name = StudentEntry.PASSWORD)
        private String password;
        @TypeConverters(URIConverter.class)
        @ColumnInfo(name = StudentEntry.URI)
        private Uri uri;
        @ColumnInfo(name = StudentEntry.CITY_ID)
        private int cityId = 0;
        @ColumnInfo(name = StudentEntry.SCORES)
        private int scores = 0;
}

获得匹配模式的最简单方法是

  1. 创建您的 @Entity 注释 classe(s) 并将它们包含在 @Database 注释 class.
  2. 中的实体中
  3. 编译 (Ctrl+F9) 然后检查生成的 Java(从 Android 视图可见)。
  4. 找到与注解为class但后缀为_Impl的@Database相同的class
  5. 在 class 中找到 createAllTables 方法。
  6. 创建语句 is/are 的 SQL 然后可用,可以复制和粘贴。
    1. 无需在 pre-packaged 数据库中创建 room_master_table。

使用这种方法克服了 Room 的一些细微差别。例如,对于 cityId 和 Scores,如果你有 Integer 而不是 int,我相信,那么 NOT NULL 约束就不需要了。

您的情况如何

指定int cityId = 0;,只是说当使用默认构造函数构建时该值将为0,它很可能导致分配0。

更重要的是 int(与任何 Java 基元一样)不能为空。因此,Room 隐含地添加了 NOT NULL 约束。但是,Integer,一个对象可以为 null,因此不会添加 NOT NULL 约束(它实际上比这更复杂,因此建议让 Room 完成工作代表你)。

What edits need to be changed for this schema?

使用 Integer 而不是 int 可能会起作用,尽管 getter 和 setter 可能会干扰这一点(注释处理进行的更复杂的处理)。