Realm-java: Realm objects can only be accessed on the thread they where created.

Created on 12 Dec 2014  Â·  10Comments  Â·  Source: realm/realm-java

Doing a testing transition from GreenDAO to Realm and it getting this all over the place. Would be nice to be able to reference objects across threads.

For example, in my Android application, I have a User object in the Application class. I naturally need to check the user from virtually anywhere, which seems to call for extra work for the programmer and more calls to the db in Realm.

Most helpful comment

@Queatz Using a Realm across Threads
The only rule to using Realm across threads is to remember that Realm, RealmObject or RealmResults instances cannot be passed across threads. When you want to access the same data from a different thread, you should simply obtain a new Realm instance (i.e. Realm.getInstance(Context context) or its cousins) and get your objects through a query. The objects will map to the same data on disk, and will be readable & writeable from any thread! <-- :)

All 10 comments

@Queatz Using a Realm across Threads
The only rule to using Realm across threads is to remember that Realm, RealmObject or RealmResults instances cannot be passed across threads. When you want to access the same data from a different thread, you should simply obtain a new Realm instance (i.e. Realm.getInstance(Context context) or its cousins) and get your objects through a query. The objects will map to the same data on disk, and will be readable & writeable from any thread! <-- :)

@sergeyfitis Yes I have read. :) More like a feature request. Something like this might work also:

public class App extends Application {
    public User getUser() {
        return mUser.forCurrentThread();
    }
}

I'm guessing the general workaround is similar to:

public class App extends Application {
    public User getUser() {
        return Realm.getInstance(getContext()).where(User.class).equalTo("id", mUserId).findFirst();
    }
}

Would that be a proper replacement?

Another use case - this one might be blocking. I wrap the creation/updating/deletion of objects and allow registering in-memory callbacks for any objects, it basically looks like this:

dbWrapper.bindCallback(aRealmObject, new BindCallback() { ... });

And any time aRealmObject is updated, dbWrapper.update(aRealmObject) is also called, which in turn calls the BindCallback.

I'm running into a few things:

  • aRealmObject can't be used directly because it can't be used across threads for the callbacks.
  • Can't store a reference to specific objects in Realm and fetch the real object later (no object ids / primary keys)
  • Can't easily add an ID field by adding a class between RealmObject and the object classes because objects have to directly subclass RealmObject.

I guess an id field could be added to every object, checked for uniqueness, and so on, but that seems like custom doing all the work that Realm should be doing. :/

just an initial quick comment: there already is a PR for primary keys. It's
been stalled a bit, but we will get back to it for sure.

On Fri, Dec 12, 2014 at 9:13 PM, Jacob Ferrero [email protected]
wrote:

Another use case - this one might be blocking. I wrap the
creation/updating/deletion of objects and allow registering in-memory
callbacks for any objects, it basically looks like this:

dbWrapper.bindCallback(aRealmObject, new BindCallback() { ... });

And any time aRealmObject is updated, dbWrapper.update(aRealmObject) is
also called, which in turn calls the BindCallback.

I'm running into a few things:

  • aRealmObject can't be used directly because it can't be used across
    threads for the callbacks.
  • Can't store a reference to specific objects in Realm and fetch the
    real object later (no object ids / primary keys)
  • Can't easily add an ID field by adding a class between RealmObject
    and the object classes because objects have to directly subclass
    RealmObject.

I guess an id field could be added to every object, checked for
uniqueness, and so on, but that seems like custom doing all the work that
Realm should be doing. :/

—
Reply to this email directly or view it on GitHub
https://github.com/realm/realm-java/issues/669#issuecomment-66828220.

The following method is not working

Realm.getInstance(getContext())

@manmohansoni See https://realm.io/docs/java/latest/#configuring-a-realm

Realm.getInstance(Context) API has been removed.

you can use the copyFromRealm() method, to have a copy of your users and save it globally and use it where ever you want.

Although you typically just need to send primary keys between the threads and requery the object if it's needed.

"Using it globally whereever you want" goes against the rule of consistency, there is no guarantee that the object will be always up to date that way.

you can use the copyFromRealm() method, to have a copy of your users and save it globally and use it where ever you want.

So that instance saved in global will be managed by repository pattern, doesn't it?

The tricky thing is that if you have a detached object, then it's unlikely to be managed properly unless you listen to Realm updates for the given table somewhere.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pawlo2102 picture pawlo2102  Â·  3Comments

jjorian picture jjorian  Â·  3Comments

CNyezi picture CNyezi  Â·  3Comments

mithrann picture mithrann  Â·  3Comments

nolanamy picture nolanamy  Â·  3Comments