Как сохранить ссылки на RealmObjects - PullRequest
1 голос
/ 11 января 2020

Рассмотрим следующие подклассы 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 к существующему экземпляру объекта Visit myVisit. Вы заметите, что в addTimeSlot я копирую измененный экземпляр Visit в Realm. Мой вопрос - при этом также сохранится только что созданный объект TimeSlot?

Связанная проблема - когда я получаю myVisit из Realm, есть ли гарантия, что объекты TimeSlot в myVisit.timeslots будут в том же порядке, что и при Я их добавил?

1 Ответ

1 голос
/ 15 января 2020

Ответы на большинство ваших вопросов приведены в документах Realm, , если вы знаете, где искать . Многие из этих вопросов упоминаются в основных документах, и тогда вам нужно найти правильную страницу API. И иногда прибегают к простой попытке.

Вы заметите, что в addTimeSlot я копирую измененный экземпляр Visit в Realm. Мой вопрос - при этом также сохранится только что созданный объект TimeSlot?

Это правильно. Документы для copyToRealmOrUpdate гласят: «Это глубокое копирование или обновление, т. Е. Все ссылочные объекты будут либо скопированы, либо обновлены». *

Вы ввели потенциальную проблему. Ваша первая строка addTimeSlot немедленно изменяет объект Visit. Это хорошо в случае, если объект Visit неуправляем, или если вы запустили транзакцию Realm вне вызова addTimeSlot. Но если это не так, вы получите исключение, касающееся «Попытки изменить объект вне транзакции записи». Ваш метод основан на том, что вы всегда работаете с неуправляемой версией объекта и вручную копируете каждое изменение обратно в область. Это не совсем рекомендуемый подход, так как вы представляете возможность несинхронизации объектов c. Лучше всегда иметь дело с управляемыми объектами.

Вы также получаете доступ к переменной с именем myRealm, которая, как я полагаю, является глобальной ссылкой на ваше Царство. Обратите внимание, что в случае управляемого объекта вы можете получить доступ к функции getRealm(), чтобы получить область для объекта и избежать глобальных / передаваемых параметров.

Итак, лучше: -

  1. Добавьте Visit в Царство при его создании
  2. В addTimeSlot, используйте результат getRealm(), чтобы проверить, что Visit управляется. Если это так, добавьте TimeSlot в Realm и RealmList.

Мне интересно, как работает ваш первичный ключ TimeSlot.

В любом случае, вернемся к вашим вопросам. .

когда я получаю myVisit из Realm, есть ли гарантия, что объекты TimeSlot в myVisit.timeslots будут в том же порядке, в котором я их добавил?

Да , A RealmList заказан. Вы можете добавить элементы либо в конец, либо вставив с помощью RealmList. Это, очевидно, было бы излишним, если бы заказ не был сохранен. См. документы .

В документах упоминается, что неуправляемые объекты похожи на простые POJO. Из того, что я понимаю, если я создам экземпляр подкласса RealObject и никогда не буду копировать его в Realm, он останется "неуправляемым".

Правильно.

Но что произойдет, если я добавлю его в экземпляр RealmList, который является частью "управляемого" RealmObject?

Это обсуждается здесь . В таком случае ваш список является списком управляемых областей, и применяется следующее утверждение:

Можно добавить неуправляемые объекты в RealmList, который уже управляется. В этом случае объект будет прозрачно скопирован в Realm с использованием Realm.copyToRealm (RealmModel, ImportFlag ...) или Realm.copyToRealmOrUpdate (RealmModel, ImportFlag ...), если он имеет первичный ключ.

Обратите внимание, что ваша существующая ссылка на объект относится к неуправляемой версии объекта, поэтому будьте осторожны. Изменение его полей не изменит управляемую версию. На данный момент лучше отказаться от неуправляемой версии и иметь дело только с управляемым объектом.

Я понимаю, почему вы запутались. Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...