LoginSignup
9

More than 5 years have passed since last update.

Realm for Javaでupdate操作の時に注意すべきこと

Last updated at Posted at 2016-03-04

2017/06/16追記
いつの間にかこのような場合の正しい方法が公式docに記載されてました。
今後はこっちを参照してもらうほうが良いです。
https://realm.io/docs/java/latest/#iterations--snapshots

ただし、何らかの理由で、新しいバージョンが使えない人たち向けにこの情報は残しておきます。

古い情報だよ!

Realmを使っていて、ある条件にヒットするデータを探して、検索に使用した値をアップデートしたいことってよくあると思います。

具体的に言うとこういうコードの場合

mRealm.beginTransaction();
RealmResults<Obj> results = mRealm.where(Obj.class).equalTo("status", 0).findAll();
int resultCount = results.size();

for (int count = 0; count < resultCount; ++count) {
  Obj obj = results.get(count);
  obj.setStatus(1);
}
mRealm.commitTransaction();

これ、行けそうに見えて、実際に実行すると、java.lang.ArrayIndexOutOfBoundsExceptionが発生してひどく悲しい気分になれます。

某所で質問したところ、最初の検索条件に使用しているパラメーターを途中で書き換えているためにRealmResults<Obj>自体が更新され配列が減っているために起こっているとのこと。

なので正解のコードはこんな感じになるらしい。

mRealm.beginTransaction();
RealmResults<Obj> results = mRealm.where(Obj.class).equalTo("status", 0).findAll();

while(results.size() > 0){
  Obj obj = results.get(0);
  obj.setStatus(1);
}
mRealm.commitTransaction();

iteratorを使えという話はこんなことになっているので無理ということで。
ConcurrentModificationException when using iterators methods #640
https://github.com/realm/realm-java/issues/640

自動更新を止めるAPI追加の方向で動いているらしい
https://github.com/realm/realm-java/commits/stk/waitforchange

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9