theanilpaudel
theanilpaudel

Reputation: 3478

Realm data not updated in android using copyToRealmOrUpdate method

I'm trying to add and retrieve data using Realm, like this

RealmController realmController = RealmController.with(this).getInstance();

    FirstTime firstTime = new FirstTime();
    firstTime.setFirstTime(1);
    realmController.addFirstTime(firstTime);
    Timber.d("firs time %s",realmController.getFirstTime().getFirstTime());


    FirstTime firstTime1 = new FirstTime();
    firstTime1.setFirstTime(2);
    realmController.addFirstTime(firstTime1);
    Timber.d("firs time updated %s",realmController.getFirstTime().getFirstTime());

realmController is not null and the realmcontroller.addFirstTime() method is like this

public void addFirstTime(FirstTime firstTime){
    Timber.d("adding first time %s",firstTime.getFirstTime());
    realm.beginTransaction();
    realm.copyToRealmOrUpdate(firstTime);
    realm.commitTransaction();
}

And my FirstTime class is like this

public class FirstTime extends RealmObject{
//0 = firstime; 1 = not firstime
@PrimaryKey
int firstTime;

public int getFirstTime() {
    return firstTime;
}

public void setFirstTime(int firstTime) {
    this.firstTime = firstTime;
}

}

The getFirstTime() in RealController is like this

public FirstTime getFirstTime() {

    return realm.where(FirstTime.class).findFirst();
}

So in the first code part, first Timber is giving 1, which is okay but the second Timber i.e

Timber.d("firs time updated %s",realmController.getFirstTime().getFirstTime());

should give me the updated value that is 2 but it is giving me 1, the old value.

Upvotes: 0

Views: 2665

Answers (1)

EpicPandaForce
EpicPandaForce

Reputation: 81539

The method copyToRealmOrUpdate() will:

  • if you give it an unmanaged object, then

    • if there is no managed RealmObject found in the Realm with the given primary key, then it will insert a new item into the Realm with that given primary key

    • if there is a managed RealmObject found in the Realm with the given primary key, then it will save all of the fields from the object into the managed RealmObject (so the object with the given primary key is updated)

  • if you give it a managed object, then

    • if the managed RealmObject belongs to the same Realm and is from the same thread, then it is immediately returned

.

if (object instanceof RealmObjectProxy && ((RealmObjectProxy)object).realmGet$proxyState().getRealm$realm() != null && ((RealmObjectProxy)object).realmGet$proxyState().getRealm$realm().getPath().equals(realm.getPath())) {
    return object;
}

In your case, you are creating a new, unmanaged object

FirstTime firstTime1 = new FirstTime(); // unmanaged object

Then you set it a new primary key value, previously not found in the database

firstTime1.setFirstTime(2); // setting primary key

Then you add it to the database

realm.beginTransaction();
realm.copyToRealmOrUpdate(firstTime1); // copy, or update if primary key exists in db
realm.commitTransaction();

This is a new object with a new primary key, so it gets copied into the Realm.

In order to modify an existing managed RealmObject, you'd need to either modify the existing instance, by obtaining a managed RealmObject via a query:

realm.executeTransaction(... {
    FirstTime time = realm.where(FirstTime.class).equalTo("id", 1).findFirst();
    time.setSomeValue("blah"); // <-- update the instance in db
});

Or use copyToRealmOrUpdate() (or insertOrUpdate()) with the same primary key value:

final FirstTime time = new FirstTime();
time.setId(1); // existing ID
time.setSomeValue("blah"); // new value for field
realm.executeTransaction(... {
    //realm.copyToRealmOrUpdate(time); //if you do not use the managed proxy, use insertOrUpdate() instead
    realm.insertOrUpdate(time);
});

P.S.: The Ravi Tamada Realm tutorial is garbage, you should refer to this article series along with its corresponding Github repository instead.

Upvotes: 2

Related Questions