7

I made some simple project for test, but i'm having some trouble with delete. It won't work. I can add contact normally, but when I try to delete it, nothing happens and i don't have any erros. Here is my code:

Entity

@Entity
public class Contact {

    @PrimaryKey(autoGenerate = true)
    private int id;

    @ColumnInfo(name = "contact_name")
    private String contactName;

    @ColumnInfo(name = "contact_number")
    private String contactNumber;

    @ColumnInfo(name = "contact_image")
    @Nullable
    private String contactImage;

...

My Dao:

@Dao
public interface ContactDao {

    @Query("SELECT * FROM Contact")
    LiveData<List<Contact>> getContacts();

    @Query("SELECT * FROM Contact WHERE id = :contact_id")
    Contact getContactById(int contact_id);

    @Insert
    void addContact(Contact contact);

    @Delete
    void deleteContact(Contact contact);
}

ViewModel:

public class ContactViewModel extends AndroidViewModel {

    private LiveData<List<Contact>> contacts;
    private ContactsDatabase contactsDatabase;

    public ContactViewModel(@NonNull Application application) {
        super(application);

        contactsDatabase = ContactsDatabase.getINSTANCE(this.getApplication());
        contacts = contactsDatabase.contactDao().getContacts();
    }

    public LiveData<List<Contact>> getContacts() {
        return contacts;
    }

    public void deleteContact(Contact contact) {
        new deleteAT(contactsDatabase).execute(contact);
    }

    private class deleteAT extends AsyncTask<Contact, Void, Void> {

        private ContactsDatabase contactsDatabase;

        deleteAT(ContactsDatabase db) {
            this.contactsDatabase = db;
        }

        @Override
        protected Void doInBackground(Contact... contacts) {
            contactsDatabase.contactDao().deleteContact(contacts[0]);
            return null;
        }
    }
}

Any solutions ?

moondaisy
  • 4,303
  • 6
  • 41
  • 70
mark_donys
  • 71
  • 1
  • 2
  • 1
    How are you calling `deleteContact()`? Are you sure the contact you are passing in has the right `id`? – Emmanuel May 18 '18 at 16:07
  • I get reference of viewmodel by ViewModelProviders.of().... And then I call deleteContact() through viewModel. That is the contact i previously added also through viewModel. I gues id should be auto generated if i'm correct ? – mark_donys May 18 '18 at 18:38

3 Answers3

2

In some cases it might be better to add a custom delete by-id instead of using the auto-generated delete by-object.

In this case it'd be

    @Query("DELETE FROM Contact WHERE id = :contact_id")
    void deleteContactById(int contact_id);

See https://stackoverflow.com/a/47554641/6513193 for more info.

Atemu
  • 295
  • 3
  • 12
1

Take a look at the generated addContact() code. It doesn't set the id on your Contact instance so you need to do it yourself.

@Entity
public class Contact {
    @PrimaryKey(autoGenerate = true)
    private long id;

    //...
}

@Dao
public interface ContactDao {
    @Insert
    long addContact(Contact contact); //returns autogenerated id

    @Delete
    void deleteContact(Contact contact);
}

Then this should work:

long insertedId = dao.addContact(contact);
contact.setId(insertedId);
dao.deleteContact(contact);
0

To elaborate on the other answer you can simply use contact.setId(myDatabase.addContact(contact))

Then later on your local instance of contact will have the correct ID set allowing it to be deleted if necessary.

Also worth noting that this case is only possible when the primary key gets generated for the first time, as it's possible to insert an entry with no primary key but it's impossible to pull a pre-existing entry from a database without a primary key.

Jameson
  • 190
  • 1
  • 11