2016-10-12 3 views
0

В нашем приложении мы добавили новый первичный ключ к одному из наших элементов (это было довольно давно, на самом деле). Естественно, миграция была необходима. Проблема в том, что это практически невозможно проверить, потому что никто не может действительно сказать, как производить эти объекты в первую очередь (и intellij не дает никаких ответов ни по какой причине)Realm Migration - инициализировать новый первичный ключ как int

В любом случае, вот моя миграция -код:

public class CustomMigration implements RealmMigration{ 

    private int currentKey = 0; 

    public void migrate(DynamicRealm realm, long oldVersion, long newVersion){ 
     RealmSchema schema = realm.getSchema(); 
     if(oldVersion <= 4){} 
      if(schema.contains("AvailableCandidate"){ 
       if(!schema.get("AvailableCandidate").hasField("pos")){ 
        .addField("pos", int.class, FieldAttribute.PRIMARY_KEY) 
         .transform(new RealmObjectSchema.Function() { 
          @Override 
          public void apply(DynamicRealmObject obj) { 
           obj.setInt("pos", currentKey++); 
          } 
         }); 
       } 
      } 
      // 
      // here be more code 
      // 
      oldVersion = 5; 
     } 
    } 
} 

обратить особое внимание на переменную currentKey. Я понял, что преобразование будет работать как итератор, а currentKey должен увеличиваться каждый раз, когда преобразование будет итерации.

Проблема в том, что до сих пор есть пользователи, которые, похоже, получают эту ошибку, и, похоже, currentKey не увеличивается.

Какое решение этой неприятной проблемы?

Edit: исключение, ткань выплюнуть является следующее:

"pos" cannot be a primary key, it already contains duplicate values: 0 
+0

Я не совсем уверен, почему это произошло, но [этот пример должен работать] (https://github.com/realm/realm-java/issues/3068#issue-162264733) – EpicPandaForce

+0

Я не изменяю типы PK, хотя мы добавили совершенно новый. Возможно ли, что те пользователи, которые испытывают ошибку, уже частично прошли миграцию и, следовательно, имеют одну запись с PK из 0? – TormundThunderfist

+0

Проверьте обходное решение здесь https://github.com/realm/realm-java/issues/2167#issuecomment-175442772 Это то, что мы должны документировать ... – beeender

ответ

1

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

public class CustomMigration implements RealmMigration{ 

    private int currentKey = 0; 

    public void migrate(DynamicRealm realm, long oldVersion, long newVersion){ 
     RealmSchema schema = realm.getSchema(); 
     if(oldVersion <= 4){} 
      if(schema.contains("AvailableCandidate"){ 
       if(!schema.get("AvailableCandidate").hasField("pos")){ 
        .addField("pos", int.class, FieldAttribute.INDEXED) 
        .transform(new RealmObjectSchema.Function() { 
         @Override 
         public void apply(DynamicRealmObject obj) { 
          obj.setInt("pos", currentKey++); 
         } 
        }) 
        .addPrimaryKey("pos"); 
       } 
      } 
      // 
      // here be more code 
      // 
      oldVersion = 5; 
     } 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if(obj == null) { 
      return false; 
     } 
     return CustomMigration.class.equals(obj.getClass()); 
    } 

    @Override 
    public int hashCode() { 
     return CustomMigration.class.hashCode(); 
    } 
}