woshidan's blog

そんなことよりコードにダイブ。

Realmのインスタンスを取得する前にmigrationを常に行うかどうか判定させたい

RealmはAPIが動作が軽量でシンプルで気軽に使えるといわれるAndroid用のDBの一種ですが、 まだまだMigration周りはめんどくさいようです。

Realmを使用したアプリの場合、一度インストールされたアプリ内のスキーマを変更するにはMigrationが必要になりまして、 一度Migrationを行うと、その後ずっとMigrationを行ったスキーマのバージョンを指定する必要があります。

そのAPIがややこしかった(参考)のですが、最近少し洗練されてきました。

// 最近のMigrationに際したschemaを指定するAPI.
// https://realm.io/docs/java/latest/ を元にスキーマのバージョン管理とは関係ない行を削除
RealmConfiguration config = new RealmConfiguration.Builder(context)
  .schemaVersion(42)
  .migration(new MyMigration()) // Realmインスタンスの取得時にMigrationを行わせたい場合、migrationメソッドを呼ぶと必要があればMigrationを行う
  .build();

さて、本題はここからです。

上記のMigrationのコードを複数の箇所で実行されるように記述すると下記の例外が起こりました。

java.lang.IllegalArgumentException: Configurations cannot be different if used to open the same file. 

Cached configuration: 
realmFolder: /data/data/com.exmaple.woshidan/files
realmFileName : default.realm
canonicalPath: /data/data/com.exmaple.woshidan/files/default.realm
key: [length: 0]
schemaVersion: 1
migration: com.exmaple.woshidan.realm.Migration@537c0428
deleteRealmIfMigrationNeeded: false
durability: FULL
schemaMediator: io.realm.DefaultRealmModuleMediator@480c5030

New configuration: 
realmFolder: /data/data/com.exmaple.woshidan/files
realmFileName : default.realm
canonicalPath: /data/data/com.exmaple.woshidan/files/default.realm
key: [length: 0]
schemaVersion: 1
migration: com.exmaple.woshidan.realm.Migration@53858418 // Migrationクラスのインスタンスが違う!!
deleteRealmIfMigrationNeeded: false
durability: FULL
schemaMediator: io.realm.DefaultRealmModuleMediator@480c5030

sakebook.hatenablog.com

を参考にすると、Migrationのインスタンスが違うそうです。そんな...という感じですが、 上の記事で紹介されている下記issueのように、Migrationクラスのequalsをオーバーライドしてしのぎました。

public class Migration implements RealmMigration {
    // https://github.com/realm/realm-java/issues/1919#issuecomment-165375852
    @Override
    public boolean equals(Object o) {
        return o instanceof Migration;
    }

migration quesstion · Issue #1919 · realm/realm-java · GitHub

びっくり!!