如何持久保存引用的RealmObjects

问题描述 投票:1回答:1

考虑以下RealmObject子类

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;
  }  
 } 
}  

在我的代码的其他地方,我执行以下操作

myVisit.addTimeSlot(new TimeSlot(30));

向访问对象TimeSlot的现有实例添加新的myVisit。您会注意到,在addTimeSlot中,我将修改后的Visit实例复制到Realm。我的问题-这样还会保留刚创建的TimeSlot对象吗?

一个相关问题-当我从Realm检索myVisit时,是否可以保证myVisit.timeslots中的TimeSlot对象与添加它们时的顺序相同?

java android realm persistence
1个回答
1
投票

您的大多数问题在Realm文档中得到了回答,如果您知道要看的地方。主要文档中提示了很多这些问题,然后您需要找到正确的API页面。有时只能尝试一下。

您会注意到,在addTimeSlot中,我将修改后的Visit实例复制到Realm。我的问题-这样还会保留刚创建的TimeSlot对象吗?

是的。 copyToRealmOrUpdate的文档状态:“这是深层副本或更新,即所有引用的对象都将被复制或更新。”

尽管您已经引入了潜在的问题。您的第一行addTimeSlot立即修改Visit对象。在Visit对象不受管理的情况下,或者在addTimeSlot调用之外启动了Realm事务的情况下,这很好。但是,如果不是这种情况,那么您将收到有关“尝试在写事务之外修改对象”的异常。您的方法依赖于您始终对对象的非托管版本进行操作,并将每个更改手动复制回Realm。实际上,这不是推荐的方法,因为这可能会导致对象不同步。最好始终处理托管对象。

您还正在访问名为myRealm的变量,我认为该变量是对您的Realm的全局引用。请注意,对于托管对象,可以访问getRealm()函数以检索对象的领域,并避免使用全局变量/传递参数。

所以,最好是:-

  1. [创建时将Visit添加到领域
  2. addTimeSlot中,使用getRealm()的结果来验证是否管理了Visit。如果是这样,请将TimeSlot添加到领域和领域列表。

不过,我对您的TimeSlot主键的工作方式很感兴趣。

无论如何,回到您的问题。

当我从Realm检索myVisit时,是否可以保证myVisit.timeslots中的TimeSlot对象与添加它们时的顺序相同?

是。订购了RealmList。您可以将元素添加到末尾或通过插入RealmList来添加。如果未存储订单,这显然是多余的。参见the docs

文档提到非托管对象就像简单的POJO。据我了解,如果我创建RealObject子类实例并且从不费心将其复制到Realm,它将保持“不受管”状态。

正确。

但是如果我将它添加到“托管” RealmObject的一部分的RealmList实例中会发生什么?

对此进行了讨论here。然后,您的列表就是一个托管领域列表,该语句适用:

可以将非托管对象添加到已经托管的RealmList中。在这种情况下,如果对象具有主键,则可以使用Realm.copyToRealm(RealmModel,ImportFlag ...)或Realm.copyToRealmOrUpdate(RealmModel,ImportFlag ...)将对象透明地复制到Realm。

尽管请注意,您现有的对该对象的引用是该对象的非托管版本,所以要小心。更改其字段不会更改托管版本。此时,最好放弃您的非托管版本,仅处理托管对象。

我明白你为什么感到困惑。希望对您有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.