1

外部キーによって子が関連付けられている場合、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)
4

1 に答える 1