I am trying to abstract the usage of Realm by creating a Singleton (which i think what the realm instances are) Class.
I am unable to access the data from the created Singleton Class.
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
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! 馃嵒