Instance closing. This Realm instance has already been closed, making it unusable.

1,839 views
Skip to first unread message

Mykhailo Kovalyk

unread,
Feb 5, 2015, 7:30:01 AM2/5/15
to realm...@googlegroups.com
Problem: Exception: IllegalStateException:  This Realm instance has already been closed, making it unusable.
Description: I have Base  DAO class for each Class and have methods like:

protected abstract T readRealm(int key); 

@Nullable
    @Override
    public T read(int key) {
        mRealm = Realm.getInstance(getContext());
        try {
            return readRealm(key);
        } finally {
            mRealm.close();
        }
    }


@Override
    protected CityInfo readRealm(int key) {
        CityInfo info;
        info = mRealm.where(CityInfo.class).equalTo("cityId", key).findFirst();
        return info;
    }

So I thought with this I ensure thread safety and correct open\closing handling.. But I tried - 
public String getLastUpdateTime(int cityId) {
        final CityInfo city = mCityInfoDao.read(cityId);
        if (city == null || city.getLastUserUpdate() == null)
            return "";
        else
            return city.getLastUserUpdate();
    }

.. and got Exception. does this mean that I need to have open connection whenever I used readed data??
And one more thing.. What about design? Is it wasteful to open\close each time? 
Thank you!

Emanuele Zattin

unread,
Feb 5, 2015, 7:48:31 AM2/5/15
to Mykhailo Kovalyk, realm...@googlegroups.com
Hello Mykhailo,

unfortunately it's a bad pattern you are trying to use for several reasons:

1) Opening and closing realms is a relatively expensive operation, especially it's it's he first Realm being instantiated in a thread.
2) As the exception suggests doind this is not legal:

Realm realm = Realm.getInstance(context);
myObject = realm.where(...).findFirst();
realm.close(); // From this moment on using realm or myObject is illegal

myVar = myObject.getFiesd(); // BOOM!

This happens because Realm data is never copied to memory and is always accessed in real time from the Realm. This is one of the features that gives Realm its speed and consistency.

What is your specific use case? Maybe we can help you find a better way to proceed.

--
Emanuele Zattin



--
You received this message because you are subscribed to the Google Groups "Realm Java" group.
To unsubscribe from this group and stop receiving emails from it, send an email to realm-java+...@googlegroups.com.
To post to this group, send email to realm...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/realm-java/a4f92c8d-efa0-4d0f-8a05-75e6cdea6b97%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



{#HS:69670891-446#}

Mykhailo Kovalyk

unread,
Feb 5, 2015, 8:20:12 AM2/5/15
to realm...@googlegroups.com
Thank you for quick reply! Hm.. ok, I will try not to close Realm when reading right after reading... but how to make sure I'm closing Realm after reading... I'm trying not to mix Models with Data AccessLayer.. 
Another idea about multithreading. What if I surround all CRUD operation with try\catch and if exception is IllegalStateException -  get Realm for this Thread and repeat operation:
    @Override
    public void create(@Nullable T object) {
        try {
            createRealm(object);
        } catch (IllegalStateException ex) {
            mRealm = Realm.getInstance(getContext());
            createRealm(object);
        }
    }


четвер, 5 лютого 2015 р. 14:30:01 UTC+2 користувач Mykhailo Kovalyk написав:

Emanuele Zattin

unread,
Feb 5, 2015, 8:27:11 AM2/5/15
to Mykhailo Kovalyk, realm...@googlegroups.com
I'm not sure a DAL is the best suited option for a framework like Realm, which already feels like an ORM.
My suggestion is to set up a Looper background thread that acts as a worker thread for all your write operations. You can see an example in our adapter example (https://github.com/realm/realm-java/tree/master/examples/adapterExample/src/main/java/io/realm/examples/realmadapters).
Your UI thread should only perform Realm reads and delegate all the writes to the worker thread.
Once you have this setup it's pretty easy to setup proper closing of your Realm instances.

--
Emanuele Zattin



On Thu, Feb 5, 2015 at 1:20 PM UTC, Mykhailo Kovalyk <mishak...@gmail.com> wrote:
Thank you for quick reply! Hm.. ok, I will try not to close Realm when
reading right after reading... but how to make sure I'm closing Realm after
reading... I'm trying not to mix Models with Data AccessLayer..
Another idea about multithreading. What if I surround all CRUD operation
with try\catch and if exception is IllegalStateException - get Realm for
this Thread and repeat operation:
@Override
public void create(@Nullable T object) {
try {
*createRealm*(object);

} catch (IllegalStateException ex) {
mRealm = Realm.getInstance(getContext());
*createRealm*(object);

}
}


четвер, 5 лютого 2015 р. 14:30:01 UTC+2 користувач Mykhailo Kovalyk написав:



On Thu, Feb 5, 2015 at 12:48 PM UTC, Help <he...@realm.io> wrote:
Hello Mykhailo,

unfortunately it's a bad pattern you are trying to use for several reasons:

1) Opening and closing realms is a relatively expensive operation, especially it's it's he first Realm being instantiated in a thread.
2) As the exception suggests doind this is not legal:

Realm realm = Realm.getInstance(context);
myObject = realm.where(...).findFirst();
realm.close(); // From this moment on using realm or myObject is illegal

myVar = myObject.getFiesd(); // BOOM!

This happens because Realm data is never copied to memory and is always accessed in real time from the Realm. This is one of the features that gives Realm its speed and consistency.

What is your specific use case? Maybe we can help you find a better way to proceed.

--
Emanuele Zattin



On Thu, Feb 5, 2015 at 12:30 PM UTC, Mykhailo Kovalyk <mishak...@gmail.com> wrote:
--
You received this message because you are subscribed to the Google Groups "Realm Java" group.
To unsubscribe from this group and stop receiving emails from it, send an email to realm-java+...@googlegroups.com.
To post to this group, send email to realm...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/realm-java/a4f92c8d-efa0-4d0f-8a05-75e6cdea6b97%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



{#HS:69670891-446#}

Mykhailo Kovalyk

unread,
Feb 5, 2015, 8:35:50 AM2/5/15
to realm...@googlegroups.com
Thanks again for quick response. ok. I undestood your recommendation. Thanks!


четвер, 5 лютого 2015 р. 14:30:01 UTC+2 користувач Mykhailo Kovalyk написав:
Problem: Exception: IllegalStateException:  This Realm instance has already been closed, making it unusable.
Reply all
Reply to author
Forward
0 new messages