首页 > 解决方案 > SQLiteConstraintException:NOT NULL 约束失败,即使在声明了默认值之后

问题描述

在一个正在进行的 android 项目中,几乎所有的数据库查询都是用老式方法编写的。使用DataHelperDatabaseOpenHelper

在这种方法中,所有插入查询都工作得很好。

由于该项目尚未发布,因此可以Room在其中引入 ORM for android。由于某种原因,我们无法将所有旧数据库代码转换为Room兼容代码。因此,我们决定使用Room旧方法创建数据库并保留所有旧操作。并且任何新的操作都会添加到RoomDaos 中。

供您参考,以前的老派模型代码创建表语句如下:

CREATE TABLE IF NOT EXISTS subscriber(
_id integer, 
number text primary key not null, 
name text, 
lookup_key text not null, 
presencestate integer not null default 4, 
presencenote text, 
subscriberimagehash text, 
last_online_time integer default 0, 
isfavourite integer not null default 0, 
buddy_public_key text default '', 
buddy_seed text default '')

我创建了所有与旧表结构相同的实体。这是同一个订阅者表的实体类;

@Entity(tableName = "subscriber")
public class Subscriber{
    public int _id;

    @NonNull
    @PrimaryKey
    public String number = SlothDefault.number;

    public String name;

    @NonNull
    @ColumnInfo(name = "lookup_key")
    public String lookUpKey = SlothDefault.lookUpKey;

    @Nullable
    @ColumnInfo(name = "presencestate")
    public int presencesState = 4;

    @Nullable
    @ColumnInfo(name = "presencenote")
    public String presenceNote = "";

    @Nullable
    @ColumnInfo(name = "subscriberimagehash")
    public String subscriberImageHash;

    @Nullable
    @ColumnInfo(name = "last_online_time")
    public Date lastOnlineTime = new Date(0);

    @Nullable
    @ColumnInfo(name = "isfavourite")
    public boolean isFavorite = false;

    @NonNull
    @ColumnInfo(name = "buddy_public_key")
    public String buddyPublicKey = "";

    @NonNull
    @ColumnInfo(name = "buddy_seed")
    public String buddySeed = "";
}

现在,问题来了。这是以前在表中插入新订户时运行良好的代码:

try {
        ContentValues values = new ContentValues();
        values.put(KEY_NUMBER, number);
        values.put(KEY_ID, ContactEngine.getContactIDFromNumber(context, number));
        String name = ContactEngine.getContactNamefromNumber(context, number);
        values.put(KEY_NAME, name == null ? "" : name);
        values.put(KEY_PRESENCE_NOTE, " ");
        values.put(KEY_PHONE_LOOKUP, ContactEngine.getContactLookupKey(context, number));
        values.put(KEY_PRESENCE_STATE, 4);
        long count = readableDatabase.insert(SUBSCRIBER_TABLE, null, values);
        if (count > 0) {
            context.getContentResolver().notifyChange(SUBSCRIBER_URI, null);
            context.getContentResolver().notifyChange(CONTACTS_URI, null);
            Log.i("datahelper", "subsciber added " + number);
        }
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        Log.d("DataHelper", "CreateSubscriber: ", e);
        return false;
    }

此代码在创建旧式数据库之前可以正常工作。但是现在这段代码显示了以下异常:

E/SQLiteDatabase: Error inserting name=Mir Monsoor Hossain number=8801811412834 lookup_key=3224i90e3d5809e0669e.3789r2238-41394B044145434D45454B0437454D4D293943.2748r4007-41394B044145434D45454B0437454D4D293943.393i1471.1894r6295-41394B044145434D45454B0437454D4D293943
_id=8540 presencenote=  presencestate=4
    android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: subscriber.isfavourite (code 1299)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:783)
        at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
        at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
        at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1548)
        at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1417)
        at com.revesoft.itelmobiledialer.databaseentry.DataHelper.createSubscriber(DataHelper.java:932)
        at com.revesoft.itelmobiledialer.service.DialerService.addSubsriber(DialerService.java:2651)
        at com.revesoft.itelmobiledialer.signalling.SIPProvider$SubscriberProcessorThread.run(SIPProvider.java:12403)

我试图使该字段显式可为空,但这无济于事。

@Nullable
@ColumnInfo(name = "isfavourite")
public boolean isFavorite = false;

如何在不更改任何先前插入语句的情况下解决此异常?并为该字段设置默认值?

标签: androidsqliteandroid-roomandroid-jetpack

解决方案


推荐阅读