Realm-java: Singleton Class for Abstraction. realm access from incorrect thread.

Created on 23 Mar 2020  路  8Comments  路  Source: realm/realm-java

Goal

I am trying to abstract the usage of Realm by creating a Singleton (which i think what the realm instances are) Class.

Actual Results

I am unable to access the data from the created Singleton Class.

Steps & Code to Reproduce

Context.java

public class FsxContext {
    private static Realm db = null;
    private static RealmConfiguration config = null;
    private static boolean Processing;

    public static void Init(Context context) {
        if (db != null) return;
        if (config == null) Configure(context);

        db = Realm.getInstance(config);
    }

    private static void Configure(Context context) {
        if (config != null) return;

        Realm.init(context);

        config = new RealmConfiguration.Builder().name("fsxMV.realm").schemaVersion(0).migration(new Migration()).build();

        Realm.setDefaultConfiguration(config);
    }

    private static void Begin() {
        Processing = true;
        db.beginTransaction();
    }

    public RealmModel Add(RealmModel model) {
        if (!Processing) Begin();

        db.insertOrUpdate(model);

        return model;
    }

    public static boolean Commit() {
        Processing = false;
        try {
            db.commitTransaction();
            return true;
        } catch (Exception e) {
            // log exception
            return false;
        }
    }

    public static Realm GetContext() {
        return db;
    }
}

Repository.java

public class TicketRepository implements ITicketRepository {
    private Realm _context = FsxContext.GetContext();
    public List<Ticket> GetTickets() {
        List<Ticket> tickets = _context.where(Ticket.class).findAll();
        return _context.copyFromRealm(tickets);
    }
}

AppLayer

public class TripModule extends ReactContextBaseJavaModule {
    private final ITicketRepository _ticketRepository;
    private final ReactApplicationContext _reactContext;
    public TripModule(@NonNull ReactApplicationContext reactContext) {
        super(reactContext);

        _reactContext = reactContext;
        FsxContext.Init(_reactContext.getApplicationContext());

        _ticketRepository = new TicketRepository();
    }

    @ReactMethod
    public void GetTickets(Callback successCallback, Callback errorCallback) {
        try {
            List<Ticket> tickets = _ticketRepository.GetTickets();

            successCallback.invoke(new Gson().toJson(tickets));
        } catch (Exception e) {
            errorCallback.invoke(e.getMessage());
        }
    }

    @NonNull
    @Override
    public String getName() {
        return "TripModule";
    }
}

I am using RN btw. Though it works perfectly fine in a very straight forward approach in the app layer but since it is a Singleton it should still be accessible right?

If i'm not mistaken this should be running in a single thread but it throws an error: realm access from incorrect thread. realm objects can only be accessed on the thread they were created

O-Community

All 8 comments

creating a Singleton (which i think what the realm instances are)

Realm instances are reference-counted thread-local instances, where getInstance() increments the counter for the thread, close() decrements the counter for the thread, and most importantly a given thread-local Realm instance can only be closed and used in any way on the thread where it was created.

Therefore, if you want to abstract away your Realm usage, then you want to use a ThreadLocal.

Oh. Thanks a lot for the tip. I'm in a bit of a very tight deadline and doesn't have the luxury of time to run through the docs (though i've already read some). Thank you very much for informing me on where i lacked and the how the instances actually works, i'll let you know the outcome.

In general we advice against abstracting Realm away. You will likely loose some of the benefits as you will most likely "dump it down" if you aim to make a generic DB layer that you could possibly replace with another DB at some point. The effort will also likely be bigger than actually just replacing Realm at a later point in case you want to.

@sshanzel I'll close this for now. Also please use the Forum for "questions" as we try to keep github issues just to bugs and feature requests. Thanks!

In general we advice against abstracting Realm away. You will likely loose some of the benefits as you will most likely "dump it down" if you aim to make a generic DB layer that you could possibly replace with another DB at some point. The effort will also likely be bigger than actually just replacing Realm at a later point in case you want to.

Hmmm that makes sense. Thank you very much for responding though yes i feel this issue was inappropriate to mention at your GitHub repo, i honestly admit it. Sorry for the trouble!

In general we advice against abstracting Realm away. You will likely loose some of the benefits as you will most likely "dump it down" if you aim to make a generic DB layer that you could possibly replace with another DB at some point. The effort will also likely be bigger than actually just replacing Realm at a later point in case you want to.

Though it's not actually the plan, to remove Realm in the future, we just do it as a practice to not make the app tightly coupled with any other things that we add on the app, who knows there might be a time where a feat we need might not be supported but on the others, they do. But still, what you said really makes a point

Technically to abstract Realm away completely, you need to put all queries on a background looper thread, but still retain a reference to each RealmResults while they are being observed.

This is what I do in https://github.com/Zhuinden/realm-monarchy/blob/52c29c7330345badfb3884d52f7540f9f81a42f4/monarchy/src/main/java/com/zhuinden/monarchy/Monarchy.java#L176-L279

Wow, thank you very much for the reference! I better start taking a look at it now! Cheers! 馃嵒

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bryanspano picture bryanspano  路  3Comments

Merlin1993 picture Merlin1993  路  3Comments

AlbertVilaCalvo picture AlbertVilaCalvo  路  3Comments

AAChartModel picture AAChartModel  路  3Comments

wezley98 picture wezley98  路  3Comments