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?
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);