Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Realm Update Error #2939

Closed
rikmenify opened this issue Jun 5, 2016 · 10 comments
Closed

Realm Update Error #2939

rikmenify opened this issue Jun 5, 2016 · 10 comments
Labels

Comments

@rikmenify
Copy link

rikmenify commented Jun 5, 2016

First i already create Bill Object then i try to create updating Object using same ID, because i want to update the realm that have relation to my Bill_ID, but i causes error. it said value already exists,

This is what i try when i want to update

realm.beginTransaction();
                    Bill updateBill = realm.createObject(Bill.class);
                    updateBill.setBill_ID(bill);
                    DetailMenu menu = realm.createObject(DetailMenu.class);
                    menu.setMenuID(8);
                    menu.setMenuName(String.valueOf(menuName.getText()));
                    menu.setMenuPrice(Price);
                    menu.setQuantity(Qty);
                        for (int i = 0; i < adapter.getPersonMenuObjList().size(); i++) {
                            PersonInMenu pim = realm.createObject(PersonInMenu.class);
                            pim.setPersonID(adapter.getPersonMenuObjList().get(i).getPersonID());
                            pim.setStatus(adapter.getPersonMenuObjList().get(i).isStatus());
                            menu.personInMenus.add(pim);
                        }

                    updateBill.detailmenu.add(menu);
                    realm.copyToRealmOrUpdate(updateBill);
                    realm.commitTransaction();
                    realm.close();

this is my model

public class Bill extends RealmObject {


    @PrimaryKey private String Bill_ID;
    public RealmList<DetailMenu> detailmenu;
    public RealmList<DetailPerson> detailperson;
    private String name;
    private int price;

    public RealmList<DetailPerson> getDetailperson() {
        return detailperson;
    }

    public void setDetailperson(RealmList<DetailPerson> detailperson) {
        this.detailperson = detailperson;
    }

    public RealmList<DetailMenu> getDetailmenu() {
        return detailmenu;
    }

    public void setDetailmenu(RealmList<DetailMenu> detailmenu) {
        this.detailmenu = detailmenu;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) { this.price = price; }

    public String getBill_ID() {
        return Bill_ID;
    }

    public void setBill_ID(String bill_ID) {
        Bill_ID = bill_ID;
    }

}
public class DetailMenu extends RealmObject {

    @PrimaryKey
    private int MenuID;
    private int Quantity;
    private String MenuName;
    private int MenuPrice;
    public RealmList<PersonInMenu> personInMenus;

    public RealmList<PersonInMenu> getPersonInMenus() {
        return personInMenus;
    }

    public void setPersonInMenus(RealmList<PersonInMenu> personInMenus) {
        this.personInMenus = personInMenus;
    }

    public DetailMenu() {
        super();
    }

    public int getMenuPrice() {
        return MenuPrice;
    }

    public void setMenuPrice(int menuPrice) {
        MenuPrice = menuPrice;
    }

    public int getMenuID() {
        return MenuID;
    }

    public void setMenuID(int menuID) {
        MenuID = menuID;
    }

    public String getMenuName() {
        return MenuName;
    }

    public void setMenuName(String menuName) {
        MenuName = menuName;
    }

    public int getQuantity() {
        return Quantity;
    }

    public void setQuantity(int quantity) {
        Quantity = quantity;
    }


}

public class PersonInMenu extends RealmObject {

    @PrimaryKey
    private int PersonID;
    private boolean Status;

    public PersonInMenu() {
        super();
    }

    public int getPersonID() {
        return PersonID;
    }

    public void setPersonID(int personID) {
        PersonID = personID;
    }

    public boolean isStatus() {
        return Status;
    }

    public void setStatus(boolean status) {
        Status = status;
    }
}
@nhachicha
Copy link
Collaborator

Hi @rikmenify

since your model uses primary key, can you try use createObject that takes a primary key parameter instead.

Bill updateBill = realm.createObject(Bill.class, bill);
// ...
DetailMenu menu = realm.createObject(DetailMenu.class, menuID);
//...
PersonInMenu pim = realm.createObject(PersonInMenu.class, adapter.getPersonMenuObjList().get(i).getPersonID());

also in your example you're using the same id menu.setMenuID(8); this will throw an exception in case of duplicate since DetailMenu uses MenuID as a primary key
Cheers,

@rikmenify
Copy link
Author

i'm sorry i want to clarify this,

even i want to create new object of DetailMenu, i need to use realm.createObject( class, primary key) ? or i can use realm.createObject(class) and i set my primary key after that ?

and for the last, i have to use realm.copyToRealmOrUpdate for my updatebill only right ? because i already add all the menu and menuinperson in their parent. please help, because i still confuse about realm concept

@kneth
Copy link
Member

kneth commented Jun 7, 2016

If you have a model class with a primary key, you must provide the value of the primary key when creating an object. The alternative is to create a plain Java object, set the primary key and then copy the object to your Realm. copyToRealmOrUpdate() will check if an object with the primary key exists and update the field of the object if it exists.

@rikmenify
Copy link
Author

so its better with copyToRealmOrUpdate() if i have primary key in my attribute right ? thanks for the support..

@rikmenify
Copy link
Author

so i'm updating my code like this

realm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        Bill updateBill = realm.where(Bill.class).equalTo("Bill_ID", bill).findFirst();
                        DetailMenu menu = realm.createObject(DetailMenu.class);

                        menu.setMenuID(MenuID);
                        menu.setMenuName(String.valueOf(menuName.getText()));
                        menu.setMenuPrice(Price);
                        menu.setQuantity(Qty);
                        for (int i = 0; i < adapter.getPersonMenuObjList().size(); i++) {
                            PersonInMenu pim = realm.createObject(PersonInMenu.class);
                            pim.setPersonID(adapter.getPersonMenuObjList().get(i).getPersonID());
                            pim.setStatus(adapter.getPersonMenuObjList().get(i).isStatus());
                            menu.personInMenus.add(pim);
                        }

                        updateBill.detailmenu.add(menu);
                        realm.copyToRealmOrUpdate(updateBill);
                    }
                });

but it's ended with io.realm.exceptions.RealmPrimaryKeyConstraintException: Value already exists: 1

@Zhuinden
Copy link
Contributor

Zhuinden commented Jun 8, 2016

Do this:

realm.executeTransaction(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                    Bill updateBill = realm.where(Bill.class).equalTo("Bill_ID", bill).findFirst();
                    DetailMenu menu = new DetailMenu();

                    menu.setMenuID(MenuID);
                    menu.setMenuName(String.valueOf(menuName.getText()));
                    menu.setMenuPrice(Price);
                    menu.setQuantity(Qty);
                    for (int i = 0; i < adapter.getPersonMenuObjList().size(); i++) {
                        PersonInMenu pim = new PersonInMenu();
                        pim.setPersonID(adapter.getPersonMenuObjList().get(i).getPersonID());
                        pim.setStatus(adapter.getPersonMenuObjList().get(i).isStatus());
                        menu.personInMenus.add(pim);
                    }

                    updateBill.detailmenu.add(menu);
                    realm.copyToRealmOrUpdate(updateBill);
                }
            });

@kneth
Copy link
Member

kneth commented Jun 9, 2016

@rikmenify Please try what @Zhuinden suggests and report back - thanks.

@rikmenify
Copy link
Author

rikmenify commented Jun 11, 2016

i've tried it, and i got this error @kneth

Process: com.example.rikirikmen.billsplit, PID: 31338 java.lang.NullPointerException: Attempt to invoke virtual method 'boolean io.realm.RealmList.add(io.realm.RealmModel)' on a null object reference at com.example.rikirikmen.billsplit.DialogActivity$1$1.execute(DialogActivity.java:101)

i try to get the Log of my Object and there is no null, please help

06-11 18:02:56.785 31338-31338/com.example.rikirikmen.billsplit I/Object: 6 true
06-11 18:02:56.785 31338-31338/com.example.rikirikmen.billsplit I/Object: 7 true
06-11 18:02:56.785 31338-31338/com.example.rikirikmen.billsplit I/Object: 8 false
06-11 18:02:56.785 31338-31338/com.example.rikirikmen.billsplit I/Object: 9 false
06-11 18:02:56.785 31338-31338/com.example.rikirikmen.billsplit I/Object: 10 false

@Zhuinden
Copy link
Contributor

@rikmenify Whoops! My mistake, I forgot to initialize your RealmList.

           realm.executeTransaction(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                    Bill updateBill = realm.where(Bill.class).equalTo("Bill_ID", bill).findFirst();
                    DetailMenu menu = new DetailMenu();
                    RealmList<PersonInMenu> personInMenus = new RealmList<>(); //added line
                    menu.personInMenus = personInMenus; //added line
                    menu.setMenuID(MenuID);
                    menu.setMenuName(String.valueOf(menuName.getText()));
                    menu.setMenuPrice(Price);
                    menu.setQuantity(Qty);
                    for (int i = 0; i < adapter.getPersonMenuObjList().size(); i++) {
                        PersonInMenu pim = new PersonInMenu();
                        pim.setPersonID(adapter.getPersonMenuObjList().get(i).getPersonID());
                        pim.setStatus(adapter.getPersonMenuObjList().get(i).isStatus());
                        menu.personInMenus.add(pim);
                    }

                    updateBill.detailmenu.add(menu);
                    realm.copyToRealmOrUpdate(updateBill);
                }
            });

@rikmenify
Copy link
Author

rikmenify commented Jun 11, 2016

wait.. i still dont get it why i need to initialize RealmList with that,
plus what is personInMenus values ?
i'm sorry , i'm newbie in Realm.

i created something like this before in my other activity and it worked, i dont know why i need that things you know.. here is the sample i created in my other activity

realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {

                Bill bill = realm.createObject(Bill.class);
                bill.setBill_ID(getNextKeyBill());
                bill.setName(Name);
                bill.setPrice(Price);
                for (int i = 0; i < Qty ; i++ ) {

                    if (i == 0) {
                        DetailPerson person = realm.createObject(DetailPerson.class);
                        person.setPersonID(getNextKey());
                        person.setPersonName("Me");
                        person.setPersonPrice(0);
                        bill.detailperson.add(person);

                    }
                    else
                    {
                        DetailPerson person = realm.createObject(DetailPerson.class);
                        person.setPersonID(getNextKey());
                        int a = i+1;
                        person.setPersonName("Person " + a);
                        person.setPersonPrice(0);
                        bill.detailperson.add(person);

                    }
                }
                }
        });

actually, it worked.. thankyou @Zhuinden, thankyoou @kneth

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 17, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

5 participants