IllegalArgumentException: имя поля не существует в объекте при выполнении миграции

Я пытаюсь перенести Realm с версии 0 на 1. У меня есть POJO следующим образом:

@Parcel(implementations = {OrganizerRealmProxy.class},
        value = Parcel.Serialization.BEAN,
        analyze = {Organizer.class})
public class Organizer extends RealmObject {

    @PrimaryKey
    private long Id;
    private String email;
    private String displayName;
    private Boolean self;
    ...


}

И в методе миграции я делаю:

RealmObjectSchema organizerSchema = schema.create("Organizer")
                    .addPrimaryKey("Id")
                    .addField("email", String.class)
                    .addField("displayName", String.class)
                    .addField("self", Boolean.class);

Но я получаю исключение:

Caused by: java.lang.IllegalArgumentException: Field name doesn't exist on object 'Organizer': Id
at io.realm.RealmObjectSchema.checkFieldExists(RealmObjectSchema.java:500)
at io.realm.RealmObjectSchema.addPrimaryKey(RealmObjectSchema.java:297)
at org.granitebaysda.bradapp.utils.RealmMigration.migrate(RealmMigration.java:20)
at io.realm.BaseRealm$2.onResult(BaseRealm.java:578)
at io.realm.RealmCache.invokeWithGlobalRefCount(RealmCache.java:242)
at io.realm.BaseRealm.migrateRealm(BaseRealm.java:565)
at io.realm.Realm.migrateRealm(Realm.java:1062)
at io.realm.Realm.migrateRealm(Realm.java:1051)
at io.realm.Realm.createInstance(Realm.java:231)
at io.realm.RealmCache.createRealmOrGetFromCache(RealmCache.java:114)
at io.realm.Realm.getInstance(Realm.java:191)
at org.granitebaysda.bradapp.MainActivity.onStart(MainActivity.java:114)at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171)
at android.app.Activity.performStart(Activity.java:5241)at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2157)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233) 
at android.app.ActivityThread.access$800(ActivityThread.java:135) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:136) 
at android.app.ActivityThread.main(ActivityThread.java:5001) 
at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515)

Версия Realm: 0.87.2

ОБНОВИТЬ

После использования addField("id", String.class, FieldAttribute.PRIMARY_KEY, FieldAttribute.REQUIRED) вместо addPrimaryKey я начал получать другое исключение:

io.realm.exceptions.RealmMigrationNeededException: Field 'id' does
support null values in the existing Realm file. Remove @Required or 
@PrimaryKey from field 'id' or migrate using 
io.realm.internal.Table.convertColumnToNotNullable()

Код моего класса Complete Migration выглядит следующим образом:

public class RealmMigration implements io.realm.RealmMigration {
    @Override
    public void migrate(DynamicRealm dynamicRealm, long oldVersion, long newVersion) {

        // DynamicRealm exposes an editable schema
        RealmSchema schema = dynamicRealm.getSchema();

        if (oldVersion == 0) {

            RealmObjectSchema organizerSchema = schema.create("Organizer")
                    .addField("Id", long.class, FieldAttribute.PRIMARY_KEY)
                    .addField("email", String.class, FieldAttribute.INDEXED)
                    .addField("displayName", String.class)
                    .addField("self", Boolean.class);

            RealmObjectSchema startSchema = schema.create("Start")
                    .addField("Id", long.class, FieldAttribute.PRIMARY_KEY)
                    .addField("dateTime", String.class)
                    .addField("timeZone", String.class)
                    .addField("date", String.class);

            RealmObjectSchema endSchema = schema.create("End")
                    .addField("Id", long.class, FieldAttribute.PRIMARY_KEY)
                    .addField("dateTime", String.class)
                    .addField("timeZone", String.class)
                    .addField("date", String.class);

            RealmObjectSchema eventCreatorSchema = schema.create("EventCreator")
                    .addField("email", String.class, FieldAttribute.PRIMARY_KEY)
                    .addField("displayName", String.class);

            RealmObjectSchema AttendeeSchema = schema.create("Attendee")
                    .addField("id", String.class, FieldAttribute.PRIMARY_KEY)
                    .addField("email", String.class)
                    .addField("displayName", String.class)
                    .addField("organizer", Boolean.class)
                    .addField("self", Boolean.class)
                    .addField("responseStatus", String.class);

            RealmObjectSchema originalStartTimeSchema = schema.create("OriginalStartTime")
                    .addField("id", String.class, FieldAttribute.PRIMARY_KEY)
                    .addField("dateTime", String.class);

            RealmObjectSchema recurrenceSchema = schema.create("RecurrenceString")
                    .addField("Id", long.class, FieldAttribute.PRIMARY_KEY)
                    .addField("recurrence", String.class);

            RealmObjectSchema EventRecurrenceDetailSchema = schema.create("EventRecurrenceDetail")
                    .addField("id", String.class, FieldAttribute.PRIMARY_KEY)
                    .addField("freq", int.class)
                    .addField("byDay", int.class)
                    .addField("byDayNum", int.class)
                    .addField("until", String.class)
                    .addField("interval", String.class);

            schema.create("Item")
                    .addField("id", String.class, FieldAttribute.PRIMARY_KEY, FieldAttribute.REQUIRED)
                    .addField("kind", String.class)
                    .addField("etag", String.class)
                    .addField("status", String.class)
                    .addField("htmlLink", String.class)
                    .addField("created", String.class)
                    .addField("updated", String.class)
                    .addField("summary", String.class)
                    .addField("description", String.class)
                    .addField("location", String.class)
                    .addRealmObjectField("creator", eventCreatorSchema)
                    .addRealmObjectField("organizer", organizerSchema)
                    .addRealmObjectField("start", startSchema)
                    .addRealmObjectField("end", endSchema)
                    .addField("transparency", String.class)
                    .addField("iCalUID", String.class)
                    .addField("sequence", Integer.class)
                    .addRealmListField("attendees", AttendeeSchema)
                    .addField("recurringEventId", String.class)
                    .addRealmObjectField("originalStartTime", originalStartTimeSchema)
                    .addRealmListField("recurrence", recurrenceSchema)
                    .addRealmObjectField("recurrenceDetail", EventRecurrenceDetailSchema);


            oldVersion++;
        }
    }
}

Органайзер.java

    public class Organizer extends RealmObject {

        @PrimaryKey
        private long Id;
        @Index
        private String email;
        private String displayName;
        private Boolean self;

...

    }

Start.java

public class Start extends RealmObject {

    @PrimaryKey
    private long Id;
    private String dateTime;
    private String timeZone;
    private String date;

    public Start() {
    }
}

End.java

public class End extends RealmObject {

    @PrimaryKey
    private long Id;
    @SerializedName("dateTime")
    @Expose
    private String dateTime;
    @SerializedName("timeZone")
    @Expose
    private String timeZone;
    @SerializedName("date")
    @Expose
    private String date;

    public End() {
    }
}

EventCreator.java

public class EventCreator extends RealmObject {

    @PrimaryKey
    private String email;
    private String displayName;

    public EventCreator() {
    }
}

Посетитель.java

public class Attendee extends RealmObject {

    @PrimaryKey
    private String id;
    private String email;
    private String displayName;
    private Boolean organizer;
    private Boolean self;
    private String responseStatus;

    public Attendee() {
    }
}

OriginalStartTime.java

public class OriginalStartTime extends RealmObject {

    @PrimaryKey
    private String id;
    private String dateTime;

    public OriginalStartTime() {
    }
}

ReccurenceString.java

public class RecurrenceString extends RealmObject {

    @PrimaryKey
    private long Id;
    private String recurrence;

    public RecurrenceString() {
    }
}

EventRecurrenceDetail.java

public class EventRecurrenceDetail extends RealmObject {

    @PrimaryKey
    private String id;
    private int freq;
    private int byDay;
    private int byDayNum;
    private String until;
    private int interval;

    public EventRecurrenceDetail() {
    }
}

Item.java

public class Item extends RealmObject {

    @PrimaryKey
    private String id;
    private String kind;
    private String etag;
    private String status;
    private String htmlLink;
    private String created;
    private String updated;
    private String summary;
    private String description;
    private String location;
    private EventCreator creator;
    private Organizer organizer;
    private Start start;
    private End end;
    private String transparency;
    private String iCalUID;
    private Integer sequence;
    private RealmList<Attendee> attendees = new RealmList<>();
    private String recurringEventId;
    private OriginalStartTime originalStartTime;
    private RealmList<RecurrenceString> recurrence = new RealmList<>();
    private EventRecurrenceDetail recurrenceDetail;

    public EventRecurrenceDetail getRecurrenceDetail() {
        return recurrenceDetail;
    }

    public Item() {
    }
}

person Shajeel Afzal    schedule 19.01.2016    source источник
comment
Можем ли мы увидеть больше кода миграции? А именно, с чего вы мигрируете и на что вы мигрируете?   -  person Donn Felker    schedule 20.01.2016


Ответы (1)


Попробуй это:

RealmObjectSchema organizerSchema = schema.create("Organizer")
                .addField("Id", long.class, FieldAttribute.PRIMARY_KEY)
                .addField("email", String.class)
                .addField("displayName", String.class)
                .addField("self", Boolean.class);

addPrimaryKey необходимо вызывать для существующего поля.

---- Обновлено 22 января 2016 г. Удалить определенную версию файла Realm ----

DynamicRealm предназначен для открытия файла Realm без проверки схем.

Если вы хотите удалить файл Realm версии 0, вы можете сделать что-то вроде этого:

File file = new File(realmConfig.getPath());
if (file.exist()) {
    DynamicRealm dynamicRealm = DynamicRealm.getInstance(realmConfig);
    long version = dynamicRealm.getVersion();
    dynamicRealm.close();
    if (version == 0) {
        Realm.deleteRealm(realmConfig);
    }
}
person beeender    schedule 20.01.2016
comment
Спасибо. Но теперь я получаю исключение: RealmMigrationNeededException: Field 'id' does support null values in the existing Realm file. Remove @Required or @PrimaryKey from field 'id' or migrate using io.realm.internal.Table.convertColumnToNotNullable(). при выполнении mRealmQuery = Realm.getInstance(config).where(URLs.class).findAll(); - person Shajeel Afzal; 21.01.2016
comment
Как вы определили идентификатор? long id или Long.id? Кроме того, обратите внимание, что у нас была ошибка, которая раньше могла вызвать проблему github.com/realm/ realm-java/issues/2001 . пожалуйста, используйте последнюю версию :) 0.87.2 на данный момент. - person beeender; 21.01.2016
comment
Он имеет тип String. - person Shajeel Afzal; 21.01.2016
comment
Версия Realm: 0.87.2 - person Shajeel Afzal; 21.01.2016
comment
Я также добавил FieldAttribute.REQUIRED в качестве четвертого аргумента метода addField. - person Shajeel Afzal; 21.01.2016
comment
Как сейчас выглядит ваш Organizer? можете ли вы изменить свой вопрос в соответствии с вашим последним кодом? - person beeender; 21.01.2016
comment
Конечно, но есть несколько моделей, я обновляю их сейчас и постараюсь быть краткими. - person Shajeel Afzal; 21.01.2016
comment
Обновлено, пожалуйста, посмотрите. (и это самый длинный вопрос, который я когда-либо видел :)) - person Shajeel Afzal; 21.01.2016
comment
Существовал ли класс Item раньше? Вы только что добавили @PrimaryKey в первую версию? Если это так, вы должны использовать addPrimaryKey(id) для элемента. - person beeender; 21.01.2016
comment
Нет. Все упомянутые здесь классы не существуют в первой версии. - person Shajeel Afzal; 21.01.2016
comment
Тогда я понятия не имею. Можете ли вы поделиться своим проектом с нами? на [email protected] - person beeender; 22.01.2016
comment
И файл Realm старой версии, чтобы воспроизвести его. - person beeender; 22.01.2016
comment
Есть ли способ удалить первую версию Realm, чтобы избежать миграции? - person Shajeel Afzal; 22.01.2016