外部キーによって子が関連付けられている場合、Room DB から親が削除されないようにしようとしています。
私は学位トラッカーに取り組んでいます。タームのコースがある場合、タームは削除できません。タームにコースがない場合は、タームを削除できます。関連する用語 ID を使用してコースの数を取得しようとしています。単純な if ステートメントを使用して、コースがない場合は用語を削除し、用語のコースがある場合はポップアップ アラートを使用し、ユーザーにコースを削除するように指示します。用語を削除する前に。
TermEditorActivity.java から
switch(item.getItemId()){
...
case R.id.delete_term:
int coursecount = queryCourses(termIdSelected);
if(coursecount > 0){
AlertDialog.Builder a_builder = new
AlertDialog.Builder(TermEditorActivity.this);
a_builder.setMessage("Courses are assigned for this
term!\n\nYou must remove all courses" +
"prior to deleting this term.")
.setCancelable(false)
.setPositiveButton("Okay", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
finish();
}
});
AlertDialog deleteAllAlert = a_builder.create();
deleteAllAlert.setTitle("CANNOT DELETE TERM!!!");
deleteAllAlert.show();
return true;
}else{
mViewModel.deleteTerm();
startActivity(new Intent(TermEditorActivity.this,
MainActivity.class));
}
...
public int queryCourses(int term) {
int course = mViewModel.queryCourses(term);
return course;
}
ViewModel から:
public int queryCourses(final int term) {
int course = mRepository.queryCourses(term);
return course;
}
AppRepository から (ここで問題が発生すると思います):
public int queryCourses(final int term) {
// executor.execute(new Runnable() {
// @Override
// public void run() {
return count = courseDb.termDao().queryCourses(term);
// }
// });
// return count;
// }
or with threading:
public int queryCourses(final int term) {
executor.execute(new Runnable() {
@Override
public void run() {
count = courseDb.termDao().queryCourses(term);
}
});
return count;
}
TermDAO から:
@Query("SELECT COUNT(*) FROM course WHERE term_id = :termIdSelected")
int queryCourses(int termIdSelected);
これにより、実行時エラーが発生し、削除ボタンが押されるとクラッシュします。概念は単純です。用語の ID を使用してコース DB にクエリを実行し、用語 ID の外部キーを使用してコースの数を取得します。用語がない場合は、用語を削除して用語のリストに戻ります。コースがある場合 (カウント > 0)、ユーザーに警告し、削除せずに終了します。
スレッドなしの例外:
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
スレッドを使用すると、コースの有無にかかわらず用語が削除され、用語にコースが関連付けられている場合はアラートが表示されません。デバッグ モードで実行すると、コースが 1 つの場合に coursecount が 0 を返すため、クエリが正しく実行されません。
スレッドから値を取得するために必要なことはありますか?
RESTRICT制約に対して SQLiteConstraintException がスローされたときのランタイム エラーのクラッシュ ログを次に示します。例外を使用してもキャッチされていません。
E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1
Process: com.mattspriggs.termtest, PID: 23927
android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 1811 SQLITE_CONSTRAINT_TRIGGER)
at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:784)
at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45)
at android.arch.persistence.room.EntityDeletionOrUpdateAdapter.handle(EntityDeletionOrUpdateAdapter.java:70)
at com.mattspriggs.termtest.database.TermDao_Impl.deleteTerm(TermDao_Impl.java:144)
at com.mattspriggs.termtest.database.AppRepository$4.run(AppRepository.java:83)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)