Realm 3.7.1
I want to partial update my RealmObject:
public class Organization extends RealmObject {
@PrimaryKey
private long id;
private Boolean isReady;
private LocalizedString name;
private RealmList<RealmInt> recommendations;
public void setName(LocalizedString name) {
this.name = name;
}
public RealmList<RealmInt> getRecom() {
return recommendations;
}
public void setRecom(RealmList<RealmInt> recom) {
this.recommendations = recom;
}
}
public class LocalizedString extends RealmObject {
private RealmList<CustomString> customStringList = new RealmList<>();
public void cascadeDelete() {
customStringList .deleteAllFromRealm(); // The cascade part
deleteFromRealm(); // delete this object
}
}
public class RealmInt extends RealmObject {
private int value;
public RealmInt() {
}
public RealmInt(int val) {
value = val;
}
}
And method for update:
public Organization updateOrCreateOrg(final String incomingOrganizationJson) throws Exception {
Realm realm = Realm.getDefaultInstance();
try {
final Organization incomingOrganization = JsonUtil.gson.fromJson(incomingOrganizationJson, Organization.class);
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Log.d(TAG, "saveOrg: new Transaction: execute: Adding/Updating to Realm...");
Organization findOrganization = realm.where(Organization.class)
.equalTo(Organization.ID, organizationId)
.findFirst();
if (findOrganization != null) {
if (incomingOrganization.getName() != null) {
findOrganization.setName(incomingOrganization.getName()); // ERROR HERE!!!
}
} else {
realm.copyToRealmOrUpdate(incomingOrganization);
}
}
});
SyncManager.getSession((SyncConfiguration) Realm.getDefaultConfiguration()).uploadAllLocalChanges();
return incomingOrganization;
} catch (InterruptedException e) {
return null;
} finally {
realm.close();
Log.d(TAG, "saveOrg: FINALLY. Success close realm!"
+ " Realm.globalCount = " + Realm.getGlobalInstanceCount(Realm.getDefaultConfiguration()));
}
}
Insert is execute success. But when I want to update I get error:
updateOrCreateOrg: new Transaction: execute: Adding/Updating to Realm...
updateOrCreateOrg: FINALLY. Success close realm! Realm.globalCount = 1
Error = 'value' is not a valid managed object.
java.lang.IllegalArgumentException: 'value' is not a valid managed object.
at io.realm.OrganizationRealmProxy.realmSet$name(OrganizationRealmProxy.java:244)
at com.myproject..model.Organization.setName(Organization.java:56)
at com.myproject..service.OrganizationService$1.execute(OrganizationService.java:102)
at io.realm.Realm.executeTransaction(Realm.java:1349)
at com.myproject..service.OrganizationService.saveOrg(OrganizationService.java:63)
at com.myproject..server.AndroidWebServer.serve(AndroidWebServer.java:82)
at fi.iki.elonen.NanoHTTPD$HTTPSession.execute(NanoHTTPD.java:840)
at fi.iki.elonen.NanoHTTPD$ClientHandler.run(NanoHTTPD.java:189)
at java.lang.Thread.run(Thread.java:841)
Error in this line:
findOrganization.setName(incomingOrganization.getName())
Ya. For a managed object, an object you want to set as a linked object must also be a managed RealmObject as well, for example the return value of realm.copyToRealm(blah) or so.
I want to update findOrganization.nameby incomingOrganization.name. What I need to fix in my code?
findOrganization.setName(realm.copyToRealm(incomingOrganization.getName()));
This
findOrganization.setName(realm.copyToRealm(incomingOrganization.getName()));
work . Fine.
But this:
findOrganization.setRecom((RealmList<RealmInt>) realm.copyToRealm(incomingOrg.getRecom()));
get error:
Error = java.util.ArrayList cannot be cast to io.realm.RealmList
java.lang.ClassCastException: java.util.ArrayList cannot be cast to io.realm.RealmList
at com.myproject.service.OrganizationService$1.execute(OrganizationService.java:114)
at io.realm.Realm.executeTransaction(Realm.java:1349)
at com.myproject.service.OrganizationService.saveOrg(OrganizationService.java:63)
at com.myproject.server.AndroidWebServer.serve(AndroidWebServer.java:82)
at fi.iki.elonen.NanoHTTPD$HTTPSession.execute(NanoHTTPD.java:840)
at fi.iki.elonen.NanoHTTPD$ClientHandler.run(NanoHTTPD.java:189)
at java.lang.Thread.run(Thread.java:841)
...with your schema in mind, that should be
findOrganization.getRecom().addAll(realm.copyToRealm(incomingOrg.getRecom()));
Yes it's work.
Here code:
if (findOrganization != null) {
if (incomingOrganization.getName() != null) {
// update
findOrganization.getName().cascadeDelete();
findOrganization.setName(realm.copyToRealm(incomingOrg.getName()));
}
if (incomingOrganization.getRecom() != null) {
// update
findOrganization.getRecom().deleteAllFromRealm();
findOrganization.getRecom().addAll(realm.copyToRealm(incomingOrg.getRecom()));
}
} else { // INSERT
realm.copyToRealmOrUpdate(incomingOrg);
}
As you can see before setXXXI must call my custom method cascadeDelete() This guarantees that data will be update (not insert) every time.
And now all work fine.
Thank you for help!
Please re-open in case of further issues
Most helpful comment