2015-05-15 14 views
12

Ho seguenti classi:Android Realm copyToRealmOrUpdate crea duplicati degli oggetti nidificati

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 
} 

i miei dati dal back-end tramite retrofit & GSON, quindi devo oggetti Java pronti per l'uso in risposta.

Immaginiamo che il backend mi restituisca le stesse tre note ogni volta che lo chiamo. Quando ricevo l'elenco di oggetti nota, faccio la seguente:

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

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

Dopo che io chiamo queste righe per controllare conteggio degli oggetti archiviati:

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

Per la prima volta:

notesCount == 3; 
templatesCount == 3; 

Proprio così. Ma, se chiamo nuovamente il server, ottenere stesse note (stesso ID PrimaryKey), e chiamare fetchNotesAndSave() ancora una volta, vado a prendere questi risultati:

notesCount == 3; 
templatesCount == 6; 

Ogni volta che io chiamo copyToRealmOrUpdate(), oggetti nidificati, che sono all'interno di oggetti con primaryKey sono duplicati - non aggiornati.

C'è un modo per modificare questo comportamento? Per favore fatemi sapere se avete bisogno di ulteriori informazioni. Grazie in anticipo!

risposta

13

È perché la classe Modello non ha alcuna chiave primaria. In tal caso, questi oggetti vengono nuovamente inseriti in quanto non vi è alcuna garanzia che gli oggetti del modello di riferimento possano essere aggiornati in modo sicuro, anche se fanno parte di un altro oggetto che ha una chiave primaria.

Se si aggiunge un @PrimaryKey alla classe del modello, dovrebbe funzionare come previsto.

+1

Lo capisco, ma nel mio caso, ci sono un sacco di classi nidificate, e non posso generare '@ primaryKey' per ciascuno di essi. Ad esempio, sto usando questo trucco per gestire l'elenco di stringhe https://github.com/realm/realm-java/issues/575, quindi dovrei generare '@ PrimaryKey' per ciascuna di' RealmString'. Quello sarà un vero inferno ... –

+2

C'è qualche soluzione per mantenere le relazioni nidificate delle classi con la superclasse senza '@ PrimaryKey', quindi sono state aggiornate correttamente? –

+0

Attualmente no. Dovresti eseguire questa pulizia manualmente. –

2

Se non è possibile fornire un PK come suggerito, è possibile utilizzare il seguente lavoro per evitare duplicati.

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

Questo è stato discusso qui https://github.com/realm/realm-java/issues/2918#issuecomment-222950343 – EpicPandaForce