0

saveCourse() is supposed to kick off verifyMentor() to create and/or verify that the currently input information for a mentor is availble to be added to the CourseEntity constructor. mMentorViewModel.saveMentor(mMentor) is supposed to kick off saving the new mentor via the scheudler repository, and the scheudler repository used the MentorDAO from the database to insert the new mentor.

I read this method Android Room - Get the id of new inserted row with auto-generate, but I'm missing some fundamental knowledge of how to get the newly created mentor information.

package com.example.wguscheduler.activities;

import android.app.DatePickerDialog;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.util.Log;
import android.view.View;
import android.widget.DatePicker;
import android.widget.EditText;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

import com.example.wguscheduler.R;
import com.example.wguscheduler.entities.CourseEntity;
import com.example.wguscheduler.entities.MentorEntity;
import com.example.wguscheduler.entities.TermEntity;
import com.example.wguscheduler.viewmodel.CourseViewModel;
import com.example.wguscheduler.viewmodel.MentorViewModel;
import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class CourseAddActivity extends AppCompatActivity {

    private static final String TAG = "CourseAddActivity";
    private CourseViewModel mCourseViewModel;
    private MentorViewModel mMentorViewModel;
    private EditText mCourseTitle, mCourseStartDate, mCourseEndDate,mCourseNotes,
        mMentorFirstName, mMentorLastName, mMentorEmail, mMentorPhone;
    private MentorEntity mMentor;
    private Calendar mEndCalendar = Calendar.getInstance();
    private Calendar mStartCalendar = Calendar.getInstance();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_courses_add);

        //initialize the tool bar
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);

        //initialize the view model
        mCourseViewModel = new ViewModelProvider(this).get(CourseViewModel.class);
        mMentorViewModel = new ViewModelProvider(this).get(MentorViewModel.class);

        //initialize EditText views
        mCourseTitle = findViewById(R.id.edit_course_add_title);
        mCourseStartDate = findViewById(R.id.edit_course_add_start);
        mCourseEndDate = findViewById(R.id.edit_course_add_end);
        mCourseNotes = findViewById(R.id.edit_course_add_notes);
        mMentorFirstName = findViewById(R.id.edit_mentor_add_first);
        mMentorLastName = findViewById(R.id.edit_mentor_add_last);
        mMentorEmail = findViewById(R.id.edit_mentor_add_email);
        mMentorPhone = findViewById(R.id.edit_mentor_add_phone);

        try {
            loadStartDatePicker();
            loadEndDatePicker();
        } catch (ParseException e) {
            e.printStackTrace();
        }

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    saveCourse();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void loadStartDatePicker() throws ParseException {
        DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                mStartCalendar.set(Calendar.YEAR, year);
                mStartCalendar.set(Calendar.MONTH, monthOfYear);
                mStartCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                updateStartLabel();

            }
        };

        mCourseStartDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new DatePickerDialog(CourseAddActivity.this,date, mStartCalendar.get(Calendar.YEAR), mStartCalendar.get(Calendar.MONTH),
                        mStartCalendar.get(Calendar.DAY_OF_MONTH)).show();
            }
        });
    }

    private void updateStartLabel() {
        String myFormat = "MM/dd/yyyy";
        SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
        mCourseStartDate.setText(sdf.format(mStartCalendar.getTime()));

    }

    private void loadEndDatePicker() throws ParseException {
        DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                mEndCalendar.set(Calendar.YEAR, year);
                mEndCalendar.set(Calendar.MONTH, monthOfYear);
                mEndCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                updateEndLabel();
            }
        };

        mCourseEndDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new DatePickerDialog(CourseAddActivity.this,date, mEndCalendar.get(Calendar.YEAR), mEndCalendar.get(Calendar.MONTH),
                        mEndCalendar.get(Calendar.DAY_OF_MONTH)).show();

            }
        });
    }

    private void updateEndLabel() {
        String myFormat = "MM/dd/yyyy";
        SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
        mCourseEndDate.setText(sdf.format(mEndCalendar.getTime()));
    }

    private void saveCourse() throws ParseException{

        SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
        verifyMentor();
        int termId = getIntent().getIntExtra("termId", 0);
        //int mentorId = mMentor.getId();
        String title = mCourseTitle.getText().toString();
        String status = "Plan to Take";
        Date start = formatter.parse(mCourseStartDate.getText().toString());
        Date end = formatter.parse(mCourseEndDate.getText().toString());
        String notes = mCourseNotes.getText().toString();

        CourseEntity course = new CourseEntity(termId, mMentor.getId(), title, status, start, end, notes);
        Log.d(TAG, "saveCourse: " + course.getCourse());
        mCourseViewModel.saveCourse(course);
        onSupportNavigateUp();
    }


    private void verifyMentor() {

        String first = mMentorFirstName.getText().toString();
        String last = mMentorLastName.getText().toString();
        String phone = mMentorPhone.getText().toString();
        String email = mMentorEmail.getText().toString();

        mMentor = new MentorEntity(first, last, phone, email);
        mMentorViewModel.saveMentor(mMentor);

    }

    // add support for going back a screen
    @Override
    public boolean onSupportNavigateUp(){
        onBackPressed();
        return true;
    }

}

package com.example.wguscheduler.entities;

import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;

@Entity (tableName = "mentor_table")
public class MentorEntity {

    @PrimaryKey(autoGenerate = true)
    @NonNull
    @ColumnInfo(name = "id")
    private long mId;

    @ColumnInfo(name = "first_name")
    private String mFirstName;

    @ColumnInfo(name = "last_name")
    private String mLastName;

    @ColumnInfo(name = "phone")
    private String mPhone;

    @ColumnInfo(name = "email")
    private String mEmail;

    public MentorEntity(long mId, String mFirstName, String mLastName, String mPhone, String mEmail) {
        this.mId = mId;
        this.mFirstName = mFirstName;
        this.mLastName = mLastName;
        this.mPhone = mPhone;
        this.mEmail = mEmail;
    }

    @Ignore
    public MentorEntity(String mFirstName, String mLastName, String mPhone, String mEmail) {
        this.mId = this.mId;
        this.mFirstName = mFirstName;
        this.mLastName = mLastName;
        this.mPhone = mPhone;
        this.mEmail = mEmail;
    }

    public long  getId() {
        return mId;
    }

    public void setId(long mId) {
        this.mId = mId;
    }

    public String getFirstName() {
        return mFirstName;
    }

    public void setFirstName(String mFirstName) {
        this.mFirstName = mFirstName;
    }

    public String getLastName() {
        return mLastName;
    }

    public void setLastName(String mLastName) {
        this.mLastName = mLastName;
    }

    public String getPhone() {
        return mPhone;
    }

    public void setPhone(String mPhone) {
        this.mPhone = mPhone;
    }

    public String getEmail() {
        return mEmail;
    }

    public void setEmail(String mEmail) {
        this.mEmail = mEmail;
    }


    public String getMentor() {
        String mentor = String.format("\n" +
                        "\nMentorId: %s\n\r" +
                        "FirstName: %s\n\r" +
                        "LastName Id: %s\n\r" +
                        "Phone: %s\n\r" +
                        "Email: %s\n\r",
                        mId, mFirstName, mLastName, mPhone, mEmail);
        return mentor;
    }
}

package com.example.wguscheduler.dao;

import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.Update;

import com.example.wguscheduler.entities.MentorEntity;

import java.util.List;

@Dao
public interface MentorDAO {

    //CREATE
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertAll(List<MentorEntity> mentors);

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(MentorEntity mentor);

    //READ
    @Query("SELECT * FROM mentor_table")
    LiveData<List<MentorEntity>> getMentors();

    @Query("SELECT * FROM mentor_table WHERE id MATCH :mentorId")
    MentorEntity getMentor(long mentorId);

    //UPDATE
    @Update
    void update(MentorEntity mentor);

    //DELETE
    @Delete
    void delete(MentorEntity mentor);

}

package com.example.wguscheduler.viewmodel;

import android.app.Application;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;

import com.example.wguscheduler.database.SchedulerRepository;
import com.example.wguscheduler.entities.MentorEntity;

import java.util.ArrayList;
import java.util.List;

public class MentorViewModel extends AndroidViewModel {

    private SchedulerRepository mSchedulerRepository;
    private LiveData<List<MentorEntity>> mAllMentors;

    public MentorViewModel(@NonNull Application application) {
        super(application);
        mSchedulerRepository = SchedulerRepository.getInstance(application.getApplicationContext());
        mAllMentors = mSchedulerRepository.getAllMentors();
    }

    public LiveData<List<MentorEntity>> getAllMentors(){
        return mAllMentors;
    }

    public void addSampleData(){
        mSchedulerRepository.addSampleData();
    }

    public void saveMentor(MentorEntity mMentor) {
        mSchedulerRepository.saveMentor(mMentor);
    }
}


package com.example.wguscheduler.database;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.TypeConverters;
import androidx.sqlite.db.SupportSQLiteDatabase;

import com.example.wguscheduler.dao.AssessmentDAO;
import com.example.wguscheduler.dao.CourseDAO;
import com.example.wguscheduler.dao.MentorDAO;
import com.example.wguscheduler.dao.TermDAO;
import com.example.wguscheduler.entities.AssessmentEntity;
import com.example.wguscheduler.entities.CourseEntity;
import com.example.wguscheduler.entities.MentorEntity;
import com.example.wguscheduler.entities.TermEntity;
import com.example.wguscheduler.utilities.Converters;

@Database(entities = {TermEntity.class,
        AssessmentEntity.class,
        CourseEntity.class,
        MentorEntity.class},
        version = 13)
@TypeConverters({Converters.class})
public abstract class SchedulerDatabase extends RoomDatabase {
    public abstract CourseDAO courseDAO();
    public abstract MentorDAO mentorDAO();
    public abstract TermDAO termDAO();
    public abstract AssessmentDAO assessmentDAO();

    private static volatile SchedulerDatabase INSTANCE;

    static SchedulerDatabase getDatabase(final Context context) {
        if (INSTANCE == null) {
            synchronized (SchedulerDatabase.class) {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            SchedulerDatabase.class,
                            "scheduler_database")
                            .fallbackToDestructiveMigration()
                            .addCallback(sRoomDatabaseCallback)
                            .build();
                }
            }
        }
        return INSTANCE;
    }

    //open the database
    private static RoomDatabase.Callback sRoomDatabaseCallback = new RoomDatabase.Callback() {

        @Override
        public void onOpen(@NonNull SupportSQLiteDatabase db) {
            super.onOpen(db);

            //new PopulateSchedulerDatabase(INSTANCE).execute();
        }
    };
}

package com.example.wguscheduler.database;

import android.content.Context;
import android.util.Log;

import androidx.lifecycle.LiveData;

import com.example.wguscheduler.entities.AssessmentEntity;
import com.example.wguscheduler.entities.CourseEntity;
import com.example.wguscheduler.entities.MentorEntity;
import com.example.wguscheduler.entities.TermEntity;
import com.example.wguscheduler.utilities.CourseSampleData;
import com.example.wguscheduler.utilities.MentorSampleData;
import com.example.wguscheduler.utilities.TermSampleData;
import com.example.wguscheduler.utilities.AssessmentSampleData;

import java.text.ParseException;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class SchedulerRepository {

    private static final String TAG = "SchedulerRepository";
    private static SchedulerRepository mSchedulerRepository;

    //data lists
    private LiveData<List<TermEntity>> mAllTerms;
    private LiveData<List<CourseEntity>> mAllCourses;
    private LiveData<List<AssessmentEntity>> mAllAssessments;
    private LiveData<List<MentorEntity>> mAllMentors;

    private SchedulerDatabase mSchedulerDatabase;
    //executor to run only one thread, in order
    private Executor executor = Executors.newSingleThreadExecutor();

    //singleton creation of the scheduler repository
    public static SchedulerRepository getInstance(Context context){
        if(mSchedulerRepository == null){
            synchronized (SchedulerRepository.class) {
                if(mSchedulerRepository == null) {
                    mSchedulerRepository = new SchedulerRepository(context);
                }
            }
        }
        return mSchedulerRepository;
    }

    private SchedulerRepository(Context context){
        mSchedulerDatabase = SchedulerDatabase.getDatabase(context);
        mAllTerms = mSchedulerDatabase.termDAO().getTerms();
        mAllCourses = mSchedulerDatabase.courseDAO().getCourses();
        mAllAssessments = mSchedulerDatabase.assessmentDAO().getAssessments();
        mAllMentors = mSchedulerDatabase.mentorDAO().getMentors();
    }


    //CRUD

    //create
    public void saveTerm(TermEntity term){
        executor.execute(new Runnable() {
            @Override
            public void run() {
                mSchedulerDatabase.termDAO().insertTerm(term);
            }

        });
    }
    public void saveCourse(CourseEntity course) {

        executor.execute(new Runnable() {
            @Override
            public void run() {
                mSchedulerDatabase.courseDAO().insertCourse(course);
            }

        });
    }
    public void saveMentor(MentorEntity mMentor) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                mSchedulerDatabase.mentorDAO().insert(mMentor);
            }

        });
    }
    public void saveAssessment(AssessmentEntity assessment) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                mSchedulerDatabase.assessmentDAO().insert(assessment);
            }

        });
    }

    public void addSampleData() {

        executor.execute(new Runnable(){
            @Override
            public void run(){

                try {
                    mSchedulerDatabase.termDAO().insertAll(TermSampleData.getTerms());
                    mSchedulerDatabase.courseDAO().insertAll(CourseSampleData.getCourses());
                    mSchedulerDatabase.assessmentDAO().insertAll(AssessmentSampleData.getAssessments());
                    mSchedulerDatabase.mentorDAO().insertAll(MentorSampleData.getMentors());
                    Log.i(TAG, "addSampleData().run()" + CourseSampleData.getCourses());

                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        });

    }

    //read
    public LiveData<List<TermEntity>> getAllTerms() {
        return mAllTerms;
    }
    public LiveData<List<CourseEntity>> getAllCourses(){ return mAllCourses;}
    public LiveData<List<AssessmentEntity>> getAllAssessments() {
        return mAllAssessments;
    }
    public LiveData<List<MentorEntity>> getAllMentors() {
        return mAllMentors;
    }

    //delete
    public void deleteTerm(int termId) {

        executor.execute(new Runnable() {
            @Override
            public void run() {
                mSchedulerDatabase.termDAO().deleteTerm(termId);
            }
        });

    }

    public void deleteCourse(int courseId) {
        executor.execute(new Runnable() {

            @Override
            public void run() {
                mSchedulerDatabase.courseDAO().deleteCourse(courseId);
            }
        });
    }

    public void deleteAssessment(int assessmentId) {
        executor.execute(new Runnable() {

            @Override
            public void run() {
                mSchedulerDatabase.assessmentDAO().deleteAssessment(assessmentId);
            }
        });
    }
}

confoundr
  • 171
  • 1
  • 10

1 Answers1

1

Have you tried changing void insert(MentorEntity mentor); to long insert(MentorEntity mentor);

long insert(MentorEntity mentor); // this will return the row id


List<Long> insertAll(List<MentorEntity> mentors); // will return row ids created
Jayanth
  • 5,954
  • 3
  • 21
  • 38
  • Thank you! This set me on the correct path. I'll add the full details to a separate answer. – confoundr Jul 11 '20 at 16:52
  • @confoundr Where is the answer, I'm facing the same problem – Big_Chair Aug 29 '20 at 15:46
  • @Big_Chair I’ll post the code when I can, but ultimately it was setting the MentorDao to return a long value to the SchedulerRepository from the insert method and from the repository to the view model and then calling the method from the view model in the activity. – confoundr Aug 30 '20 at 19:20
  • @confoundr Thanks for the quick info but don't worry about it. I already asked it myself and then answered it myself too haha: https://stackoverflow.com/a/63657729/1972372 – Big_Chair Aug 30 '20 at 20:48