2015-09-22 52 views
1

我正在寫一個RealmMigration,並在那之後的幾個不同的錯誤,我想我終於明白了,但現在我得到io.realm.exceptions.RealmMigrationNeededException:索引沒有爲字段定義'首要的關鍵'。領域:沒有爲字段定義索引

我看到了一些關於需要使用table.addSearchIndex()的方法,但即使在爲每個表添加之後,我仍然會得到異常。

這是我的Migration類。

Migration.java

public class Migration implements RealmMigration { 

@Override 
public long execute(Realm realm, long version) { 
    Timber.i("Current database version: " + version); 

    /** 
    * Version 1: 
    *  Task: 
    *   Remove boolean field completed 
    *   Remove Date field completedDate 
    *  Transaction: 
    *   Add int field type 
    */ 
    if (version == 0) { 
     // Transaction 
     Table transactionTable = realm.getTable(Transaction.class); 
     transactionTable.addColumn(ColumnType.INTEGER, "type"); 
     long transactionPrimaryKeyIndex = getIndexForProperty(transactionTable, "primaryKey"); 
     long transactionTitleIndex = getIndexForProperty(transactionTable, "title"); 
     long transactionPointsIndex = getIndexForProperty(transactionTable, "points"); 
     long transactionDateIndex = getIndexForProperty(transactionTable, "date"); 
     long transactionTypeIndex = getIndexForProperty(transactionTable, "type"); 

     for (int i = 0; i < transactionTable.size(); i++) { 
      // Until now the only possible transaction was reward 
      transactionTable.setLong(transactionTypeIndex, i, Transaction.TYPE_REWARD); 
     } 

     // Task 
     Table taskTable = realm.getTable(Task.class); 

     // Go through and create Transactions for each completed Task 
     long taskPrimaryKeyIndex = getIndexForProperty(taskTable, "primaryKey"); 
     long taskCompletedIndex = getIndexForProperty(taskTable, "completed"); 
     long taskCompletedDateIndex = getIndexForProperty(taskTable, "completedDate"); 
     long taskTitleIndex = getIndexForProperty(taskTable, "title"); 
     long taskPointsIndex = getIndexForProperty(taskTable, "points"); 


     for (int i = 0; i < taskTable.size(); i++) { 
      if (taskTable.getBoolean(taskCompletedIndex, i)) { 
       transactionTable.addEmptyRowWithPrimaryKey(transactionTable.getLong(transactionPrimaryKeyIndex, transactionTable.size() - 1) + 1); 
       long j = transactionTable.size() - 1; // The new row 

       transactionTable.setString(transactionTitleIndex, j, taskTable.getString(taskTitleIndex, i)); 
       transactionTable.setLong(transactionPointsIndex, j, taskTable.getLong(taskPointsIndex, i)); 
       transactionTable.setDate(transactionDateIndex, j, taskTable.getDate(taskCompletedDateIndex, i)); 
       transactionTable.setLong(transactionTypeIndex, j, Transaction.TYPE_TASK); 
      } 
     } 

     // Finally, remove the columns we don't need any more 
     taskTable.removeColumn(getIndexForProperty(taskTable, "completed")); 
     taskTable.removeColumn(getIndexForProperty(taskTable, "completedDate")); 

     // https://realm.io/news/realm-java-0.82.0/ 
     taskTable.addSearchIndex(taskPrimaryKeyIndex); 
     transactionTable.addSearchIndex(transactionPrimaryKeyIndex); 

     Table reminderTable = realm.getTable(Reminder.class); 
     Table rewardTable = realm.getTable(Reward.class); 
     reminderTable.addSearchIndex(getIndexForProperty(reminderTable, "primaryKey")); 
     rewardTable.add(getIndexForProperty(rewardTable, "primaryKey")); 

     version++; 
    } 

    return version; 
} 

private long getIndexForProperty(Table table, String name) { 
    for (int i = 0; i < table.getColumnCount(); i++) { 
     if (table.getColumnName(i).equals(name)) { 
      return i; 
     } 
    } 
    return -1; 
} 

}

Task.java

public class Task extends RealmObject { 
    @PrimaryKey 
    private long primaryKey; 
    private String title; 
    private String description; 
    private int points; 
    private boolean hasReminders; 
    private RealmList<Reminder> reminders; 

    public static long getNextPrimaryKey(Realm realm) { 
     RealmResults<Task> tasks = realm.where(Task.class).findAllSorted("primaryKey"); 
     if (tasks.size() == 0) return 0; 
     return tasks.last().getPrimaryKey() + 1; 
    } 

    // Getters and setters 
} 

Transaction.java

public class Transaction extends RealmObject { 
    public static final int TYPE_TASK = 0; 
    public static final int TYPE_REWARD = 1; 

    @PrimaryKey 
    private long primaryKey; 
    private String title; 
    private int points; 
    private Date date; 
    private int type; 

    public static long getNextPrimaryKey(Realm realm) { 
     if (realm != null) { 
      RealmResults<Transaction> transactions = realm.where(Transaction.class).findAllSorted("primaryKey"); 
      if (transactions.size() == 0) return 0; 
       return transactions.last().getPrimaryKey() + 1; 
      } else { 
       return 0; 
      } 
     } 
    } 

    // Getters and setters 
} 
+0

你還可以發佈你的模型類嗎? –

+0

我已經添加了遷移中涉及的兩個類,類Reminder和Reward幾乎與那些使用長主鍵的類相同。 – Ben

+0

對不起,延遲迴復。我認爲這是因爲你在添加索引之前刪除了任務表中的兩列。這意味着您在開始時計算的索引不再有效。 –

回答

1

這是因爲你在任務中去除兩列表是在添加索引之前。這意味着您在開始時計算的索引不再有效。