android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed:

Reason for Exception is that Gson treats “missing” values as “null”
Caused by: android.database.sqlite.SQLiteConstraintException:
NOT NULL
constraint failed: (code 1299 SQLITE_CONSTRAINT_NOTNULL)
You might come across this error when you are using Room database on Android. This happens because the generated schema for your tables mark some of the table’s columns as NOT NULL.

For example, if you Entity class looks like this:

Model Class Book:
package com.geekscompete.gate_isro_cs.ugc_net_preparation.database.models

import androidx.room.Entity
import androidx.room.PrimaryKey
import com.geekscompete.gate_isro_cs.ugc_net_preparation.database.BaseOb

@Entity(tableName = "book")
class Book(
        @PrimaryKey(autoGenerate = true)
        var objectId: Int = 0,

        id: String ="",
        data: String = "",
        title: String ="",
        description: String ="",
        last_updated: String ="",
        logo_url: String ="",
        orderno: Int = 0,
        tags: String="",
        type: Int = -1,
        btm_color: String="#F0513C",

       var price: Int,
        var redirect_url: String,
        var tag: String
): BaseOb(id,data,title,description,last_updated,logo_url,orderno,tags,type,btm_color)

Data I am getting from API is as below:
{
id: 1,
title: "NTA UGC NET/SET/JRF - Paper 1",
description: "This book, in its third edition, is designed and developed for students who aspire to build a career in academics and research field",
image_url: "https://images-na.ssl-images-amazon.com/images/I/71%2BZPvi7ZlL.jpg",
store_logo_url: "https://images-na.ssl-images-amazon.com/images/G/01/rainier/available_at_amazon_1200x600_Nvz5h2M.png",
price: 411,
redirect_url: "https://www.amazon.in/NTA-UGC-NET-SET-JRF/dp/9353433746/ref=as_li_ss_il?crid=2EYYT7DF8WXMX&keywords=ugc+net+paper+1+2019&qid=1564293960&s=gateway&sprefix=ugc+net+,aps,281&sr=8-1-spons&psc=1&linkCode=li2&linkId=8424f35e3b5163df827e84af24007fb9&language=en_IN",
tag: "UGC NET PAPER 1"
}

There was no data field in the API response and I am parsing using Gson.
The generated columns like title, description, data and logo_url will be marked as NOT NULL. And thus, when you try to add a record with one of these values as null, you will get an SQLiteConstraintException.
val title: String
In Kotlin, this means that title can never be null.

To fix this, you just need to change the Entity class a bit, and allow the fields to be Nullable.
@Entity(tableName = "books")
data class Book(
    @PrimaryKey
    val id: Int,
    val title: String?,
    val description: String?,
    val info: String?,
    val type: Int,
    val url: String?
)

08-31 18:19:06.031 8364-8450/com.geekscompete.gate_isro_cs.ugc_net_preparation E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
    Process: com.geekscompete.gate_isro_cs.ugc_net_preparation, PID: 8364
    android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: book.data (code 1299)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:780)
        at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
        at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
        at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:51)
        at androidx.room.EntityInsertionAdapter.insert(EntityInsertionAdapter.java:97)
        at com.geekscompete.gate_isro_cs.ugc_net_preparation.database.models.BookNewDao_Impl.insertAll(BookNewDao_Impl.java:267)
        at com.geekscompete.gate_isro_cs.ugc_net_preparation.quiz_attempts.QuizListFragment_new$getBooks$1$1.run(QuizListFragment_new.kt:410)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:818)

References best:
https://techdroid.kbeanie.com/2018/11/24/room-database-kotlin-nullable-column/
https://www.bignerdranch.com/blog/when-nullability-lies-a-cautionary-tale/

No comments:

Post a Comment

Popular Posts