Home > other >  Pre-packaged database has an invalid schema Room
Pre-packaged database has an invalid schema Room

Time:04-30

Good evening. I'm trying to load a prepared database, but I'm getting an error. I came to the conclusion that due to the fact that Room finds the difference between the two columns Scored and CityId. Room expects them to be non-zero, but in the Student class they are already non-zero, as in the prepared schema. Please help me figure out what edits need to be changed for this schema.

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]}]}

Schema

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;
}

CodePudding user response:

The easiest way to get matching schema's, is to

  1. create your @Entity annotated classe(s) and include them in entities within the @Database annotated class.
  2. Compile (Ctrl F9) then examine the generated java (visible from Android View).
  3. Find the class that is the same as the @Database annotated class but suffixed with _Impl.
  4. Within the class locate the createAllTables method.
  5. The SQL for the create statement(s) is/are then available and can be copied and pasted.
    1. There is no need to create the room_master_table in the pre-packaged database.

Using this method overcomes some of the nuances of Room. For example, for cityId and Scores if you have Integer rather than int, I believe, then the NOT NULL constraint would not have been required.

What is happening in your case

Specifying int cityId = 0;, is only saying that the value will be 0 when built with the default constructor, it may well result in 0 being assigned.

What is more important is that and int (as with any java primitive) cannot be null. As such Room adds the NOT NULL constraint implicitly. However, Integer, an object can be null and thus the NOT NULL constraint is not added (it's actually even more complex than this hence the suggestion to let Room do the work on your behalf).

Please help me figure out what edits need to be changed for this schema.

Using Integer instead of int will possibly work, although getters and setters can interfere with this (the more complex processing undertaken by annotation processing).

  • Related