1

I get these errors when running @test on my database:

android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (Sqlite code 787 SQLITE_CONSTRAINT_FOREIGNKEY), (OS error - 11:Try again)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:841)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:803)
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:64)
at com.example.qwez.repository.local.QuestionDao_Impl$5.call(QuestionDao_Impl.java:138)
at com.example.qwez.repository.local.QuestionDao_Impl$5.call(QuestionDao_Impl.java:133)
at io.reactivex.internal.operators.completable.CompletableFromCallable.subscribeActual(CompletableFromCallable.java:36)
at io.reactivex.Completable.subscribe(Completable.java:2302)
at io.reactivex.Completable.blockingAwait(Completable.java:1219)
at com.example.qwez.repository.local.GameQuestionDaoTest.storeAndGet(GameQuestionDaoTest.java:63)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)
at androidx.test.internal.runner.junit4.statement.RunAfters.evaluate(RunAfters.java:61)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:104)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:392)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2252)

My test:

@RunWith(AndroidJUnit4.class)
public class GameQuestionDaoTest {

    @Rule
    public InstantTaskExecutorRule instantTaskExecutorRule = new InstantTaskExecutorRule();

    private GameDatabase gameDatabase;
    private GameDao gameDao;
    private QuestionDao questionDao;

    @Before
    public void setUp() throws Exception {
        Context context = ApplicationProvider.getApplicationContext();
        gameDatabase = Room.inMemoryDatabaseBuilder(context, GameDatabase.class)
                .allowMainThreadQueries()
                .build();
        gameDao = gameDatabase.gameDao();
        questionDao = gameDatabase.questionDao();
    }

    @After
    public void closeDb() throws IOException {
        gameDatabase.close();
    }

    @Test
    public void storeAndGet() {
        Game game = new Game("cat","diff");
        int id = (int) gameDao.insertReturnId(game);
        for(int i=0;i<5;i++){
            Question question = new Question("1", "2", "3", "4", "5");
            question.setId(id);
            questionDao.insert(question).blockingAwait();
        }
        int a = questionDao.getAll().blockingGet().size();
        assertEquals(4, a);
    }
}

My entities:

@Entity(tableName = "games")
public class Game {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    private int gameId;
}

and

@Entity(foreignKeys = @ForeignKey(entity = Game.class,
        parentColumns = "id",childColumns = "question_id",
        onDelete = ForeignKey.CASCADE),
        tableName = "questions")
public class Question {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    private int id;
}

Looked at similar questions on Stackoverflow but have not managed to find anything that can help my case. Any suggestions?

1 Answer 1

2

It would appear that you are setting the the id column of the question with the game id not the question_id column which is the column that should contain the game id as per childColumns = "question_id",.

Thus the question_id column is null and hence the conflict.

I believe you want something along the lines of

question.setQuestion_Id(id);

instead of

question.setId(id);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.