16

I'm setting a property on a realm object with another realm object which is a different class, however I'm getting the error: 'value' is not avalid managed object.

realmObject.setAnotherRealmObject(classInstance.returnAnotherRealmObjectWithValues())

The class instance receives anotherRealmObject constructor and returns it through the method with values from widgets:

public ClassInstance(AnotherRealmObject anotherRealmObject){
  mAnotherRealmObject = anotherRealmObject;
}

public AnotherRealmObject returnAnotherRealmObjectWithValues(){
       mAnotherRealmObject.setId(RandomUtil.randomNumbersAndLetters(5));
       mAnotherRealmObject.setName(etName.getText().toString());

       return mAnotherRealmObject;
}

I'm creating the new Another Realm Object the right way (I think):

mAnotherRealmObject = mRealmInstance.createObject(AnotherRealmObject.class);

Is it because I'm returning anotherRealmObject wherein it is already modified because of the passing reference?

Kim Montano
  • 2,185
  • 4
  • 26
  • 39

2 Answers2

24

Upon researching there is a method on realm objects to check if it is valid:

realmObject.isValid();

There are two ways I know how to instantiate a realmObject:

RealmObject realmObj = new RealObject(); //Invalid
RealmObject realmObj = realmInstance().createObject(RealmClass.class); //Valid

I was using parceler to pass realmObjects around. Passing a realmObject through parceler and unwrapping it and assigning it to a realmObject variable would make it invalid:

RealmObject realmObj = Parcels.unwrap(data.getParcelableExtra("realmObject"));

Solution 1 - Pass the unique identifer, then query the realm object:

int uniqueId = Parcels.unwrap(data.getParcelableExtra("uniqueId"));

Solution 2 - Pass the values, retrieve it, create a realmObject through a realmInstance and assign the values.

//Retrieve values
String value1 = Parcels.unwrap(data.getParcelableExtra("value1"));
String value2 = Parcels.unwrap(data.getParcelableExtra("value2"));

//Create realmObject 'properly'
RealmObject realmObj = realmInstance().createObject(RealmClass.class);

//Assign retrieved values
realmObj.setValue1(value1);
realmObj.setValue2(value2);

This way you won't get an invalid realm object.

Kim Montano
  • 2,185
  • 4
  • 26
  • 39
  • 3
    When create object with `RealmObject realmObj = new RealObject();`, it is actually creating a standalone `RealmObject` which is not managed by Realm yet. You can use `realmObj = realm.copyTorealm(realmObj)` to get a instance of the managed Realm object. It is better to pass the primary key then query for the object than pass the standalone object through parcel. Query with primary key in Realm should be super fast. See https://realm.io/docs/java/latest/#intents – beeender Mar 07 '16 at 07:38
4

All managed RealmObjects and RealmResults belong to a specific Realm instance. After the corresponding Realm instance gets closed, the RealmObject becomes invalid.

Like below case:

Realm realm = Realm.getInstance(context);
realm.beginTransaction();
MyObject obj = realm.createObject(MyObject.class);
realm.commitTransaction();
realm.close();

realm = Realm.getInstance(context);
realm.beginTransaction();
MyObject obj2 = realm.where(MyObject2.class).findFirst();
obj2.setObj1(obj); // Throws exception, because of the obj's Realm instance is closed. It is invalid now.
realm.commitTransaction();

You may get some ideas about control the Realm's instance life cycle through this doc

beeender
  • 3,555
  • 19
  • 32
  • Hi @beender, while you have some really good points, and I would like to read the whole java doc first, I would like to point out that I was not closing the realm instance that I was using so it's probably not the cause of my error. – Kim Montano Feb 02 '16 at 08:12
  • 1
    Do you still hold a reference to the Realm instance? If it gets GCed, the problem could happen as well. – beeender Feb 02 '16 at 08:53
  • Hi @beender, I have found the problem and the solution. I will post the answer. – Kim Montano Mar 07 '16 at 06:11
  • The number of limitations associated with Realm are mind-bending – RunLoop Feb 13 '18 at 12:17