0

I am having some issues with Room, and I am a little lost on the proper way to do this. I am trying to create a RecyclerView that shows all of the Courses that hold a certain termId.

When calling the query in the Activity, it gives me an error:

public class RelatedCourses extends AppCompatActivity {
    private TermDao termDao;
    List<Course> coursesInTerm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = getIntent();
        int termId = Integer.parseInt(intent.getStringExtra("EXTRA_ID"));
        coursesInTerm = termDao.getRelatedCourses(termId);
        setContentView(R.layout.activity_related_courses);

        CourseViewModel courseViewModel;

    }
}

2022-03-04 20:18:30.260 23510-23510/com.example.architectureexample E/AndroidRuntime: FATAL 

EXCEPTION: main
    Process: com.example.architectureexample, PID: 23510
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.architectureexample/com.example.wgu_student_scheduler.Activities.RelatedCourses}: java.lang.NullPointerException: Attempt to invoke interface method 'java.util.List com.example.wgu_student_scheduler.Database.TermDao.getRelatedCourses(int)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'java.util.List com.example.wgu_student_scheduler.Database.TermDao.getRelatedCourses(int)' on a null object reference
        at com.example.wgu_student_scheduler.Activities.RelatedCourses.onCreate(RelatedCourses.java:31)
        at android.app.Activity.performCreate(Activity.java:7009)
        at android.app.Activity.performCreate(Activity.java:7000)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6494) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

In my CourseDao it is the last Query:

@Dao
public interface CourseDao {

    @Insert
    void insert(Course course);

    @Update
    void update(Course course);

    @Delete
    void delete(Course course);

    @Query("DELETE FROM course_table")
    void deleteAllCourses();

    @Query("SELECT * FROM course_table ORDER BY startDate ASC")
    LiveData<List<Course>> getAllCourses();

    @Query("SELECT * FROM course_table WHERE termId = :termId")
    LiveData<List<Course>> getCoursesInTerm(int termId);
}

Do I need to add it to the Course Repository? I am not sure how to implement that with a variable in the argument, if so...

public class CourseRepository {

    private CourseDao courseDao;
    private LiveData<List<Course>> allCourses;

    public CourseRepository(Application application) {
        Database database = Database.getInstance(application);
        courseDao = database.courseDao();

        allCourses = courseDao.getAllCourses();
    }

    public void insert(Course course) {
        new InsertCourseAsyncTask(courseDao).execute(course);
    }

    public void update(Course course) {
        new UpdateCourseAsyncTask(courseDao).execute(course);
    }

    public void delete(Course course) {
        new DeleteCourseAsyncTask(courseDao).execute(course);
    }

    public void deleteAllCourses() {
        new DeleteCourseAsyncTask(courseDao).execute();
    }

    public LiveData<List<Course>> getAllCourses() {
        return allCourses;
    }

    private static class InsertCourseAsyncTask extends AsyncTask<Course, Void,Void> {
        private CourseDao courseDao;

        private InsertCourseAsyncTask(CourseDao courseDao) {
            this.courseDao = courseDao;
        }

        @Override
        protected Void doInBackground(Course... courses) {
            courseDao.insert(courses[0]);
            return null;
        }
    }

    private static class UpdateCourseAsyncTask extends AsyncTask<Course, Void,Void> {
        private CourseDao courseDao;

        private UpdateCourseAsyncTask(CourseDao courseDao) {
            this.courseDao = courseDao;
        }

        @Override
        protected Void doInBackground(Course... courses) {
            courseDao.update(courses[0]);
            return null;
        }
    }

    private static class DeleteCourseAsyncTask extends AsyncTask<Course, Void,Void> {
        private CourseDao courseDao;

        private DeleteCourseAsyncTask(CourseDao courseDao) {
            this.courseDao = courseDao;
        }

        @Override
        protected Void doInBackground(Course... courses) {
            courseDao.delete(courses[0]);
            return null;
        }
    }

    private static class DeleteAllCoursesAsyncTask extends AsyncTask<Void, Void,Void> {
        private CourseDao courseDao;

        private DeleteAllCoursesAsyncTask(CourseDao courseDao) {
            this.courseDao = courseDao;
        }

        @Override
        protected Void doInBackground(Void... voids) {
            courseDao.deleteAllCourses();
            return null;
        }
    }
}

Or would this be something that needs to be added to the ViewModel class to support the addition to the recyclerview?

public class CourseViewModel extends AndroidViewModel {

    private CourseRepository repository;
    private LiveData<List<Course>> allCourses;

    public CourseViewModel(@NonNull Application application) {
        super(application);
        repository = new CourseRepository(application);
        allCourses = repository.getAllCourses();
    }

    public void insert(Course course) {
        repository.insert(course);
    }

    public void update(Course course) {
        repository.update(course);
    }

    public void delete(Course course) {
        repository.delete(course);
    }

    public void deleteAllCourses() {
        repository.deleteAllCourses();
    }

    public LiveData<List<Course>> getAllCourses() {
        return allCourses;
    }

This is my first time interacting with Room, and it is a little confusing for me. I appreciate the time.

1 Answers1

0

You are calling getRelatedCourses(termId) on termDao in onCreate() of RelatedCourses without initializing termDao.

This is what is causing the error Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'java.util.List com.example.wgu_student_scheduler.Database.TermDao.getRelatedCourses(int)' on a null object reference.

Shahood ul Hassan
  • 745
  • 2
  • 9
  • 19