Search code examples
androiddatabaseviewmodelandroid-room

I am getting an error when I delete a row from room database


In my application I have a detail view of that opens whenever user clicks on a recyclerview item.

in the detail view there is a delete button that deletes item by id.

whenever I delete a row of data I get the below error

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.almaneakhaled.coutdeplat, PID: 19844
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.almaneakhaled.coutdeplat.rawmaterialsdata.RawMaterialsEntity.getRawMaterialName()' on a null object reference
        at com.almaneakhaled.coutdeplat.itemview.MaterialItemView.lambda$onCreate$0$MaterialItemView(MaterialItemView.java:81)
        at com.almaneakhaled.coutdeplat.itemview.-$$Lambda$MaterialItemView$_tUa0kDVoDvYdVg5rSyCjITsVqg.onChanged(Unknown Source:4)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
        at androidx.lifecycle.LiveData$1.run(LiveData.java:91)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7050)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)

This my code for the detail activity:

public class MaterialItemView extends AppCompatActivity {

    //define textviews to load strings from room for the intended ID
    TextView mMaterialName;
    TextView mMaterialBrand;
    TextView mMaterialWeight;
    TextView mMaterialUnitWeight;
    TextView mMaterialUnitCost;
    TextView mMaterialCostPerGm;
    TextView mMaterialAvailableQuantity;
    TextView mMaterialTotalCost;
    TextView mMaterialSupplierName;
    TextView mMaterialSupplierEmail;
    TextView mMaterialSupplierPhone;
    int mId;

    RawMaterialViewModel mMaterialViewModel;
    private static final int UPDATE_MATERIAL_ACTIVITY_REQUEST_CODE = 2;

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

        //connect each textView with its corresponding ID in the Layout material_item_view
        mMaterialName = findViewById(R.id.material_name_view);
        mMaterialBrand = findViewById(R.id.material_brand_view);
        mMaterialWeight = findViewById(R.id.material_weight_view);
        mMaterialUnitWeight = findViewById(R.id.material_weight_unit_view);
        mMaterialUnitCost = findViewById(R.id.material_unit_cost_view);
        mMaterialCostPerGm = findViewById(R.id.material_cost_per_gm_view);
        mMaterialAvailableQuantity = findViewById(R.id.material_quantity_view);
        mMaterialTotalCost = findViewById(R.id.material_total_cost_view);
        mMaterialSupplierName = findViewById(R.id.material_supplier_name_view);
        mMaterialSupplierEmail = findViewById(R.id.material_supplier_email_view);
        mMaterialSupplierPhone = findViewById(R.id.material_supplier_phone_view);


        //get the intent sent from the previous activity
        Intent intent = getIntent();
        //check if the intent is null
        if (intent != null && intent.hasExtra("ID")) {

            mId = intent.getIntExtra("ID", -1);
            // TODO: get material details based on material id

            // Set up the materialViewModel
                mMaterialViewModel = new ViewModelProvider(this).get(RawMaterialViewModel.class);
               mMaterialViewModel.findMaterialById(mId).observe(this, rawMaterialsEntity -> {
                   mMaterialName.setText(rawMaterialsEntity.getRawMaterialName());
                   mMaterialBrand.setText(rawMaterialsEntity.getRawMaterialBrand());
                   mMaterialWeight.setText(String.valueOf(rawMaterialsEntity.getUnitWeight()));
                   mMaterialUnitWeight.setText(rawMaterialsEntity.getUOM());
                   mMaterialUnitCost.setText(String.valueOf(rawMaterialsEntity.getUnitCost()));
                   mMaterialCostPerGm.setText(String.valueOf(rawMaterialsEntity.getCostPerGm()));
                   mMaterialAvailableQuantity.setText(String.valueOf(rawMaterialsEntity.getRawMaterialQuantity()));
                   mMaterialTotalCost.setText(String.valueOf(rawMaterialsEntity.getTotalCost()));
                   mMaterialSupplierName.setText(rawMaterialsEntity.getSupplierName());
                   mMaterialSupplierEmail.setText(rawMaterialsEntity.getSupplierEmail());
                   mMaterialSupplierPhone.setText(rawMaterialsEntity.getSupplierPhone());
               });
           }
        else {

            mMaterialName.setText(R.string.material_name_view_na);
            mMaterialBrand.setText(R.string.material_brand_view_na);
            mMaterialWeight.setText(R.string.material_weight_view_na);
            mMaterialUnitWeight.setText(R.string.material_uom_view_na);
            mMaterialUnitCost.setText(R.string.material_cost_view_na);
            mMaterialCostPerGm.setText(R.string.material_cost_per_gm_view_na);
            mMaterialAvailableQuantity.setText(R.string.material_quantity_view_na);
            mMaterialTotalCost.setText(R.string.material_total_cost_view_na);
            mMaterialSupplierName.setText(R.string.material_s_name_view_na);
            mMaterialSupplierEmail.setText(R.string.material_s_email_view_na);
            mMaterialSupplierPhone.setText(R.string.material_s_phone_view_na);
        }

        //define the control buttons
        ImageButton cancelButton = findViewById(R.id.materials_cancel_button_view);
        ImageButton editButton = findViewById(R.id.materials_edit_button);
        ImageButton deleteButton = findViewById(R.id.materials_delete_button);
        ImageButton emailButton = findViewById(R.id.materials_email_button);
        ImageButton callButton = findViewById(R.id.materials_call_button);

        cancelButton.setOnClickListener(view -> finish());

        editButton.setOnClickListener(view -> {
            Intent intent1 = new Intent(getBaseContext() ,RawMaterialsEditor.class);
            intent1.putExtra("ID", mId);
            startActivityForResult(intent1, UPDATE_MATERIAL_ACTIVITY_REQUEST_CODE);
        });

        deleteButton.setOnClickListener(view -> {
            mMaterialViewModel.deleteMaterial(mId);
            Intent intent1 = new Intent(this, MainActivity.class);
            finish();
        });

    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == UPDATE_MATERIAL_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
            RawMaterialsEntity material = new RawMaterialsEntity(Integer.valueOf(data.
                    getStringExtra(RawMaterialsEditor.EXTRA_REPLY_id)) ,data
                    .getStringExtra(RawMaterialsEditor.EXTRA_REPLY_NAME),
                    data.getStringExtra(RawMaterialsEditor.EXTRA_REPLY_BRAND),
                    Float.valueOf(data.getStringExtra(RawMaterialsEditor.EXTRA_REPLY_WEIGHT)),
                    Float.valueOf(data.getStringExtra(RawMaterialsEditor.EXTRA_REPLY_COST)),
                    Integer.valueOf(data.getStringExtra(RawMaterialsEditor.EXTRA_REPLY_QUANTITY)),
                    data.getStringExtra(RawMaterialsEditor.EXTRA_REPLY_S_NAME),
                    data.getStringExtra(RawMaterialsEditor.EXTRA_REPLY_S_EMAIL),
                    data.getStringExtra(RawMaterialsEditor.EXTRA_REPLY_S_PHONE),
                    data.getStringExtra(RawMaterialsEditor.EXTRA_REPLY_UOM));
            mMaterialViewModel.updateMaterial(material);
            mMaterialViewModel.costPerGm();
            mMaterialViewModel.totalCost();
        }
        else {
            Toast.makeText(
                    this.getApplicationContext(),
                    R.string.editor_insert_rm_failed,
                    Toast.LENGTH_LONG).show();
        }
    }

}

Kindly help me in fixing this error, I debugged the app it looks like that if ended the viewModel lifecycle manually it will fix the problem, but I do not know how to do that.


Solution

  • Solved the error by wrapping textviews data loaders with an if statement to check if the entity object is not null.

    mMaterialViewModel = new ViewModelProvider(this).get(RawMaterialViewModel.class);
                    mMaterialViewModel.findMaterialById(mId).observe(this, rawMaterialsEntity -> {
                        if (rawMaterialsEntity != null) {
                            mMaterialName.setText(rawMaterialsEntity.getRawMaterialName());
                            mMaterialBrand.setText(rawMaterialsEntity.getRawMaterialBrand());
                            mMaterialWeight.setText(String.valueOf(rawMaterialsEntity.getUnitWeight()));
                            mMaterialUnitWeight.setText(rawMaterialsEntity.getUOM());
                            mMaterialUnitCost.setText(String.valueOf(rawMaterialsEntity.getUnitCost()));
                            mMaterialCostPerGm.setText(String.valueOf(rawMaterialsEntity.getCostPerGm()));
                            mMaterialAvailableQuantity.setText(String.valueOf(rawMaterialsEntity.getRawMaterialQuantity()));
                            mMaterialTotalCost.setText(String.valueOf(rawMaterialsEntity.getTotalCost()));
                            mMaterialSupplierName.setText(rawMaterialsEntity.getSupplierName());
                            mMaterialSupplierEmail.setText(rawMaterialsEntity.getSupplierEmail());
                            mMaterialSupplierPhone.setText(rawMaterialsEntity.getSupplierPhone());
                        }