IllegalArgumentException:执行迁移时对象上不存在字段名称

时间:2016-01-19 20:49:02

标签: realm realm-migration

我正在尝试将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)

领域版本为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()

我的完整迁移类代码如下所示:

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++;
        }
    }
}

Organizer.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() {
    }
}

Attendee.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() {
    }
}

1 个答案:

答案 0 :(得分:4)

试试这个:

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

---- 2016年1月22日更新删除Realm文件的特定版本----

DynamicRealm旨在打开Realm文件而不检查架构。

如果要删除版本0 Realm文件,可以执行以下操作:

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);
    }
}
相关问题