web-dev-qa-db-ja.com

レルム例外「値」は有効な管理対象オブジェクトではありません

別のクラスである別のレルムオブジェクトを使用してレルムオブジェクトのプロパティを設定していますが、「値」が有効な管理対象オブジェクトではありませんというエラーが発生します。

realmObject.setAnotherRealmObject(classInstance.returnAnotherRealmObjectWithValues())

クラスインスタンスはanotherRealmObjectコンストラクターを受け取り、ウィジェットからの値を含むメソッドを介してそれを返します。

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

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

       return mAnotherRealmObject;
}

新しいAnother Realmオブジェクトを正しい方法で作成しています(私はそう思います)。

mAnotherRealmObject = mRealmInstance.createObject(AnotherRealmObject.class);

参照を渡すためにすでに変更されている別のRealmObjectを返すからですか?

12
Kim Montano

調査すると、レルムオブジェクトに有効かどうかを確認するメソッドがあります。

realmObject.isValid();

RealmObjectをインスタンス化する方法を知っている2つの方法があります。

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

パーセルを使用してrealmObjectを渡していました。パーセルを通じてrealmObjectを渡し、それをアンラップしてrealmObject変数に割り当てると、無効になります。

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

解決策1-一意の識別子を渡してから、レルムオブジェクトをクエリします。

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

解決策2-値を渡して取得し、realmInstanceを介してrealmObjectを作成して、値を割り当てます。

//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);

このようにして、無効なレルムオブジェクトを取得しません。

22
Kim Montano

管理対象のRealmObjectsおよびRealmResultsはすべて、特定のRealmインスタンスに属しています。対応するRealmインスタンスが閉じられた後、RealmObjectは無効になります。

以下のケースのように:

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();

これで、レルムのインスタンスライフサイクルの制御に関するアイデアが得られるかもしれません doc

4
beeender

管理対象オブジェクトの場合、リンクオブジェクトとして設定するオブジェクトも、管理対象RealmObjectである必要があります。

たとえば、realm.copyToRealm(blah)の戻り値などです。

1
Ahmad Arslan