Android Realm copyToRealmOrUpdate создает дубликаты вложенных объектов - программирование

Android Realm copyToRealmOrUpdate создает дубликаты вложенных объектов

У меня есть следующие классы:

public class Note extends RealmObject {

    @PrimaryKey
    private String id;

    private Template template;

    // other primitive fields, getters & setters
}

public class Template extends RealmObject {

    private String name;

    private String color;

    // other primitive fields, getters & setters
}

Я получаю свои данные из бэкэнд через Retrofit и Gson, поэтому у меня есть готовые к использованию java-объекты в ответ.

Предположим, что бэкэнд возвращает мне то же три Notes каждый раз, когда я его называю. Когда я получаю список объектов Note, я делаю следующее:

private void fetchNotesAndSave() {
    List<Notes> notes = getNotesViaRetrofit();        

    Realm realm = Realm.getInstance(mContext);
    realm.beginTransaction();
    realm.copyToRealmOrUpdate(notes);
    realm.commitTransaction();
    realm.close();
}

После этого я вызываю эти строки для проверки количества хранимых объектов:

int notesCount = mRealm.where(Note.class).findAll().size();
int templatesCount = mRealm.where(Template.class).findAll().size();

Впервые:

notesCount == 3;
templatesCount == 3;

Это правильно. Но, если я снова вызову сервер, получаю те же заметки (те же primaryKey ids) и снова вызову fetchNotesAndSave(), я получу следующие результаты:

notesCount == 3;
templatesCount == 6;

Каждый раз, когда я вызываю copyToRealmOrUpdate(), вложенные объекты, которые находятся внутри объектов с primaryKey, дублируются - не обновляются.

Есть ли способ изменить это поведение? Пожалуйста, дайте мне знать, если вам нужна дополнительная информация. Спасибо заранее!

4b9b3361

Ответ 1

Это связано с тем, что ваш класс Template не имеет первичного ключа. В этом случае эти объекты снова вставляются, поскольку нет гарантии, что объекты шаблонов, на которые ссылаются, могут быть обновлены, даже если они являются частью другого объекта с первичным ключом.

Если вы добавите @PrimaryKey в свой шаблонный класс, он должен работать так, как вы ожидаете.

Ответ 2

Если вы не можете предоставить ПК, как было предложено, вы можете использовать следующую работу, чтобы избежать дублирования.

for (Note note: notes) {
    realm.where(Note.class)
    .equalTo("id", note.getId())
    .findFirst()
    .getTemplate()
    .deleteFromRealm();
}
realm.copyToRealmOrUpdate(notes);