0

Guys, i have been Struggling with this problem from a ling time, let me explain the problem in detail.

i have one Surah Table and one aya table, one surah can have more than one ayah (one to many) so thats why what i did "created a parent child relation between Surah and Ayah throug foreign key contraint" so i added the Surah Primary key column(Surah Number - Integer) as a foreign key in the Ayah table here is the code of that

Surah Object / Surah Data Class

@Entity(tableName = "surah_table")
public class Surah {   
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "surah_number")
    private int number;

    @ColumnInfo(name = "surah_name")
    private String name;

    @ColumnInfo(name = "surah_english_name")
    private String englishName;

    @ColumnInfo(name = "surah_eng_translated_name")
    private String englishNameTranslation;

    @ColumnInfo(name = "revelationType")
    private String revelationType;

    @ColumnInfo(name = "number_of_ayahs")
    private int numberOfAyahs;

    @Ignore
    private List<Ayah> ayahs;
}

Ayah Object / Ayah Data Class

@Entity(tableName = "ayah_table",
foreignKeys = {@ForeignKey(
                entity = Surah.class,
                parentColumns = "surah_number",
                childColumns = "surah_number",
                onDelete = CASCADE)})
public class Ayah {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "ayah_number")
    private int number;

    @ColumnInfo(name = "surah_number")
    private int surahNumber;
  
    @ColumnInfo(name = "ayah_audio")
    private String audio;

    @ColumnInfo(name = "ayah_text")
    private String text;
    
    @ColumnInfo(name = "juz")
    private int juz;

    @ColumnInfo(name = "page")
    private int page;

}

Well Surah Data is succesfully inserted and saved into the table, but when i am inserting the data into ayah table then i am facing the following exception

FATAL EXCEPTION: Thread-5
Process: MyProjectPackageName, PID: 19183
android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787)

This is my Dao Interface

@Dao
public interface QuranDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(Surah surah);

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(Ayah ayah);

    @Query("SELECT * FROM surah_table WHERE surah_number =:surahNo")
    Surah isDataExist(int surahNo);

    @Query("SELECT * FROM surah_table ORDER BY surah_number ASC")
    LiveData<List<Surah>> getAllSurah();

    @Query("SELECT * FROM ayah_table ORDER BY ayah_number ASC")
    LiveData<List<Ayah>> getAllAyah();
    
}

and here is my Database Class

@Database(entities = {Surah.class, Ayah.class}, version = 9)
public abstract class QuranDatabase extends RoomDatabase {

    private static QuranDatabase instance;
    public abstract QuranDao quranDao();

    //Instance of Data Base
    public static synchronized QuranDatabase getInstance(Context context){
        if (instance ==null){
            instance = Room.databaseBuilder(context.getApplicationContext(),
                    QuranDatabase.class,"quran_database.db")
                    .addCallback(roomCallback)
                    .fallbackToDestructiveMigration()
                    .build();
        }
        return instance;
    }

    //Database Callback
    private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback(){
        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            super.onCreate(db);
            new PopulateDbAsyncTask(instance).execute();
        }
    };

    private static class PopulateDbAsyncTask extends AsyncTask<Void, Void , Void>{
        private QuranDao quranDao;
        private PopulateDbAsyncTask(QuranDatabase db){
            quranDao = db.quranDao();
        }
        @Override
        protected Void doInBackground(Void... voids) {
            Log.d("TTT", "Populate Database is Called...");
            return null;
        }
    }
}

So now anyone please guide me is this a right way of insterting the data into a table that is bind with a foreign key constrain with another table, in room data persistance library.

You know what i am thinking the foreign key column in the ayah table is not getting initialized because i the ayah object (which i am fetching from the rest API) dosnt have any this surah_number column in it. and am confused wheather i have to initialized that manually or room will automatically map it with its parent table (Surah_table) surah_number column automatically.

and if room dosnt do that then i also confused how can i do it manually, becuse data is comming from the Rest API www.aladhan.com ==> API ==> Quran Api,

or should i follow the Embeded and Relation annotation as recomneded by the documnetation. plese guys help me out from this problem.

  • Do you have one to many relationship like surah -> list of ayah?. insert surah and ayah in one transaction with the same surah_number. similarto https://stackoverflow.com/questions/47753396/android-room-handling-list-of-objects-in-an-object-and-querying-result ( check insert) – Raghunandan Dec 07 '20 at 07:55
  • @Raghunandan no I don't, but the example you have recommended through the link I know that way also, i mean never applied yet but still i know the whole flow, but wanna ask one thing the way i am using in my code is not a valid one. i have to use Embeded and relation Anotations with a relation class like SurahWithAyahs.java. where one obejct should be of type Surah and one object should be of type List. – Tayyab Husain Dec 07 '20 at 08:26
  • yes you need to insert like already mentioned. another similar question https://stackoverflow.com/questions/44667160/android-room-insert-relation-entities-using-room. – Raghunandan Dec 07 '20 at 08:29

0 Answers0