Reason for Exception is that Gson treats “missing” values as “null”
For example, if you Entity class looks like this:
Model Class Book:
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.
To fix this, you just need to change the Entity class a bit, and allow the fields to be Nullable.
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/
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.NOT NULL
constraint failed: (code 1299 SQLITE_CONSTRAINT_NOTNULL)
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)
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"
}
{
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?
)
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)
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