Reputation: 8890
Consider the following RealmObject subclasses
public class TimeSlot extends RealmObject
{
@PrimaryKey
private int value = 0;
private int hits = 0;
@LinkingObjects("ats") private final RealmResults<Visit> visits = null;
public TimeSlot(){}
public TimeSlot(int time)
{
super();
value = time;
}
...
}
public class Visit extends RealmObject
{
private RealmList<TimeSlot> timeslots = null;
public Visit()
{
super();
timeslots = new RealmList<TimeSlot>();
}
public void addTimeSlot(TimeSlot ts) throws Exception
{
this.timeslots.add(ts);
try
{
myRealm.beginTransaction();
myRealm.copyToRealmOrUpdate(this,ImportFlag.valueOf("CheckSameValuesBeforeSet"));
myRealm.commitTransaction();
}
catch(Exception e)
{
myRealm.cancelTransaction();
throw e;
}
}
}
Somewhere else in my code I do the following
myVisit.addTimeSlot(new TimeSlot(30));
to add a new TimeSlot
to an existing instance of a Visit object, myVisit
. You will note that in addTimeSlot
I am copying the modified Visit
instance to Realm. My question - doing so will also persist the freshly created TimeSlot object?
A related issue - when I retrieve myVisit from Realm is there a guarantee that the TimeSlot objects in myVisit.timeslots will be in the same order as when I added them?
Upvotes: 1
Views: 82
Reputation: 1610
Most of your questions are answered in the Realm docs, if you know where to look. A lot of these questions are hinted at in the main docs, and then you need to find the correct API page. And sometimes resort to just trying it.
You will note that in addTimeSlot I am copying the modified Visit instance to Realm. My question - doing so will also persist the freshly created TimeSlot object?
That is correct. The docs for copyToRealmOrUpdate state: "This is a deep copy or update i.e., all referenced objects will be either copied or updated."
You've introduced a potential problem though. Your first line of addTimeSlot
immediately amends the Visit
object. This is fine in the case of either the Visit
object being unmanaged, or if you have started a Realm transaction outside the call to addTimeSlot
. But if this is not the case then you will receive an exception regarding 'Attempting to modify object outside of a write transaction'. Your method relies on you always operating on the unmanaged version of the object, and manually copying each change back to the Realm. This isn't really the recommended approach, as you're introducing the possibility of objects being out of sync. Better to always deal with managed objects.
You are also accessing a variable called myRealm
, which I assume is a global reference to your Realm. Note that in the case of a managed object, you can access the getRealm()
function to retrieve the realm for the object and avoid globals/passing parameters.
So, better is to:-
Visit
to the Realm when you create itaddTimeSlot
, use the result of getRealm()
to verify it the Visit
is managed. If so, add the TimeSlot
to the Realm and the RealmList.I'm interested how your TimeSlot
primary key works though.
Anyway, back to your questions.
when I retrieve myVisit from Realm is there a guarantee that the TimeSlot objects in myVisit.timeslots will be in the same order as when I added them?
Yes. A RealmList
is ordered. You can add elements either to the end or by inserting with a RealmList
. This would obviously be redundant if the order was not stored. See the docs.
The docs mention that unmanaged objects are like simple POJOs. From what I understand if I create a RealObject subclass instance and never bother copying it to a Realm it will stay "unmanaged".
Correct.
But then what happens if I add it to a RealmList instance that is part of a "managed" RealmObject?
This is discussed here. Your list is then a managed realm list, and this statement applies:
It is possible to add unmanaged objects to a RealmList that is already managed. In that case the object will transparently be copied to Realm using Realm.copyToRealm(RealmModel, ImportFlag...) or Realm.copyToRealmOrUpdate(RealmModel, ImportFlag...) if it has a primary key.
Note though that your existing reference to the object is to an unmanaged version of the object, so be careful. Altering its fields will not alter the managed version. At this point its best to discard your unmanaged version and deal only with the managed object.
I can see why you're confused. I hope that helps.
Upvotes: 1