2016-09-14 1 views
0

レルム内のテーブル全体を更新するために何をしているのかが正しい安全なアプローチであるかどうかは不思議でした。私はこのように私のデシベルをサーバから会話のリストを受け取り、更新:レルムテーブルの更新

public class Conversation extends RealmObject { 

    private RealmList<Message> messages = new RealmList<>(); 

これは動作しますが、私はすべてのバグを見つけることができませんでした:

@Override 
public void saveConversations(final List<Conversation> conversations) { 
    realm.executeTransactionAsync(new Realm.Transaction() { 
     @Override 
     public void execute(Realm realm) { 

      // Remove all conversations and replace with the one passed in 
      // Realm does not support cascade deletes. Remove messages as well 
      // https://github.com/realm/realm-java/issues/1104 
      realm.delete(Conversation.class); 
      realm.delete(Message.class); 

      realm.copyToRealmOrUpdate(conversations); 
     } 
    }); 
} 

Conversation.javaは、内部メッセージのRealmListを持っていますそれは特にエレガントに見えません。 realm.copyToRealmOrUpdate(conversations);が間違っていたらどうなりますか?私はすべての自分のデータを失うだろう。

とにかく、これはあまり起こりそうもないことを知っていますが、より良いやり方があるのだろうかと思っていました。

PS:データベースには存在しない会話はもう望んでいないので、データベースからすべてを削除することに注意してください。

答えて

0

copyToRealmOrUpdate()が失敗した場合、トランザクションはがキャンセルされたであることを意味します。つまり、すべてのデータを失うことはありません。

個人的には、「すべて削除」というアプローチを使用していましたが、すべてのテーブルをクリアすると問題は発生しませんが、ConversationMessageを参照している(例えばUser.class)、あなたはすべての関係を無効にします。だから私は個人的にこれのようにマージすることを好む。

  • あなたは

を保存したデータをマージし、リストにないすべてのデータを削除します。

public class Contact { 
    @PrimaryKey 
    private long id; 

    @Index 
    private String name; 

    @Index 
    private String phoneNumber; 

    @Index 
    private boolean isBeingSaved; // this line is important 

    //getters, setters 
} 

次にマージ:

// background thread 
Realm realm = null; 
try { 
    realm = Realm.getDefaultInstance(); 
    final List<Contact> contacts = getContacts(); 
    realm.executeTransaction(new Realm.Transaction() { 
     @Override 
     public void execute(Realm realm) { 
      realm.insertOrUpdate(contacts); 
      realm.where(Contact.class) 
       .equalTo(ContactFields.IS_BEING_SAVED, false) // compile 'dk.ilios:realmfieldnameshelper:1.1.0' 
       .findAll() 
       .deleteAllFromRealm(); // delete all non-saved data 
         // in your case, this is where you'd handle the cascading too though manually 
      for(Contact realmContact : realm.where(Contact.class).findAll()) { // realm 0.89.0+ 
       realmContact.setIsBeingSaved(false); // reset all save state 
      } 
     } 
    }); 
} finally { 
    if(realm != null) { 
     realm.close(); 
    } 
} 
+0

は、それはかなりクールな機能だが、それは成功しなかった場合、トランザクションは元に戻すことになる気づいていませんでした。あなたのアプローチを共有してくれてありがとうございます。 – feresr

+0

うん、それは 'executeTransaction()'と同じです。それ以外の場合は、 'realm.beginTransaction()'、 'realm.commitTransaction()'、 'realm.cancelTransaction()'です。例では、失敗したときに書き込みトランザクションをキャンセルすることが非常に重要であるにもかかわらず、エラーで 'realm.cancelTransaction()'を無視することがよくあります。 – EpicPandaForce

関連する問題