房间,如何设置“字段的非空值”为假?

时间:2018-10-11 16:07:34

标签: android android-room

我想使用room在数据库中添加一个新列。我使用Room的迁移将数据库迁移到新版本,但是无法正常工作。 INTERGER字段的默认notnull值为true,这对我来说真的很麻烦。请帮我。我已经坚持了好几个小时。

我有一个Location类。

package com.example.phamf.javamvvmapp.Model;
import ...

@Entity (tableName = "location")
public class Location {

    @PrimaryKey(autoGenerate = true)
    private int id;

    private float x;

    private float y;

    private String name;


    public Location(int id, float x, float y, String name) {
        this.id = id;
        this.x = x;
        this.y = y;
        this.name = name;
    }

    public Location () {

    }

    // Getter and setter
}

我想添加一个名为type的新字段,其类型为INTEGER,所以我像

一样修改了我的Location.java文件。
package com.example.phamf.javamvvmapp.Model;
import ...

@Entity (tableName = "location")
public class Location {

    @PrimaryKey(autoGenerate = true)
    private int id;

    private int type;        

    private float x;

    private float y;

    private String name;


    public Location(int id, float x, float y, String name, int type) {
        this.id = id;
        this.x = x;
        this.y = y;
        this.name = name;
        this.type = type;
    }

    public Location () {

    }

    // Getter and setter
}

这是我的RoomDatabase类。

    @Database(entities = {Location.class}, version = 2)
    public abstract class LocationRoomDatabase extends RoomDatabase {

    private static LocationRoomDatabase DATABASE;

    public static LocationRoomDatabase getDatabase (final Context context) {

        Migration migration = new Migration(1, 2) {
            @Override
            public void migrate(@NonNull SupportSQLiteDatabase database) {
                database.execSQL("ALTER TABLE location ADD type INTEGER");
            }
        };

        if (DATABASE == null) {
            DATABASE = Room.databaseBuilder(context, LocationRoomDatabase.class, "database")
                           .addMigrations(migration).build();
    }

        return DATABASE;
    }

    public abstract LocationDAO locationDAO();
}

问题是当我运行上面的代码时,出现错误

//...

Caused by: java.lang.IllegalStateException:
   Migration didn't properly handle location(com.example.phamf.javamvvmapp.Model.Location).
Expected:
     TableInfo{..., type=Column{name='type', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, foreignKeys=[], indices=[]}
Found:
     TableInfo{..., type=Column{name='type', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0}}, foreignKeys=[], indices=[]}

//...

Expected TableInfo和Found TableInfo之间唯一不同的是“ notNull值”。期望它是真实的,但是发现不是。我意识到问题就在那里,所以我修改了迁移代码

        Migration migration = new Migration(1, 2) {
            @Override
            public void migrate(@NonNull SupportSQLiteDatabase database) {
                database.execSQL("ALTER TABLE location ADD type INTEGER not null");
            }
        };

我以为它会完美运行,但随后出现错误

Caused by: android.database.sqlite.SQLiteException: Cannot add a NOT NULL column with default value NULL (code 1 SQLITE_ERROR): , while compiling: ALTER TABLE location ADD type INTEGER not null

我还尝试将默认值添加到“类型”字段,但是它也无法正常工作

 private int type = 0;

任何解决此问题的方法,请帮助我。非常感谢。 对任何语法错误表示歉意。

1 个答案:

答案 0 :(得分:2)

我终于找到了解决方案。通过在SQL命令的“ ... ADD COLUMN column_name”之后添加“ DEFAULT someValue”。这使我的字段具有与期望的表信息匹配的默认值。 即:

sql.execSQL("ALTER TABLE table_name ADD COLUMN column_name INTEGER DEFAULT 1 not null")