Docs Menu
Docs Home
/ /
Atlas Device SDKs
/ /

Change an Object Model - Java SDK

The following examples demonstrate how to add, delete, and modify properties in a schema. First, make the required schema change. Then, increment the schema version. Finally, if the change is breaking (destructive) create a corresponding migration function to move data from the original schema to the updated schema.

Note

Versions Update on Realm Open

Assume that each schema change shown in the following example occurs after the application has used the existing schema. The new schema version numbers apply only after you open the realm and explicitly specify the new version number. In other words, you can't specify version 3 without previously specifying and using versions 0, 1, and 2.

A realm using schema version 0 has a Person object type:

public class Person extends RealmObject { // Realm schema version 0
@Required
public String firstName;
@Required
public int age;
}
class Person: RealmObject { // Realm schema version 0
var firstName: String = ""
var age: int = 0
}

The following example adds a lastName property to the original Person schema:

public class Person extends RealmObject { // Realm schema version 1
@Required
public String firstName;
@Required
public String lastName;
@Required
public int age;
}
class Person: RealmObject { // Realm schema version 1
var firstName: String = ""
var lastName: String = ""
var age: int = 0
}

The following example uses a combined fullName property instead of the separate firstName and lastName property in the original Person schema:

public class Person extends RealmObject { // Realm schema version 2
@Required
public String fullName;
@Required
public int age;
}
class Person: RealmObject { // Realm schema version 2
var fullName: String = ""
var age: int = 0
}

The following example modifies the age property in the original Person schema by renaming it to birthday and changing the type to Date:

public class Person extends RealmObject { // Realm schema version 3
@Required
public String fullName;
@Required
public Date birthday = new Date();
}
class Person: RealmObject { // Realm schema version 3
var fullName: String = ""
var birthday: Date = Date()
}

To migrate the realm to conform to the updated Person schema, set the realm's schema version to 3 and define a migration function to set the value of fullName based on the existing firstName and lastName properties and the value of birthday based on age:

public class Migration implements RealmMigration {
@Override
public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
Long version = oldVersion;
// DynamicRealm exposes an editable schema
RealmSchema schema = realm.getSchema();
// Changes from version 0 to 1: Adding lastName.
// All properties will be initialized with the default value "".
if (version == 0L) {
schema.get("Person")
.addField("lastName", String.class, FieldAttribute.REQUIRED);
version++;
}
// Changes from version 1 to 2: combine firstName/lastName into fullName
if (version == 1L) {
schema.get("Person")
.addField("fullName", String.class, FieldAttribute.REQUIRED)
.transform( DynamicRealmObject obj -> {
String name = "${obj.getString("firstName")} ${obj.getString("lastName")}";
obj.setString("fullName", name);
})
.removeField("firstName")
.removeField("lastName");
version++;
}
// Changes from version 2 to 3: replace age with birthday
if (version == 2L) {
schema.get("Person")
.addField("birthday", Date::class.java, FieldAttribute.REQUIRED)
.transform(DynamicRealmObject obj -> {
Int birthYear = Date().year - obj.getInt("age");
obj.setDate("birthday", Date(birthYear, 1, 1));
})
.removeField("age");
version++;
}
}
};
@RealmModule(classes = { Person.class })
public class Module {}
RealmConfiguration config = new RealmConfiguration.Builder()
.modules(new Module())
.schemaVersion(3) // Must be bumped when the schema changes
.migration(new Migration()) // Migration to run instead of throwing an exception
.build();
val migration = object: RealmMigration {
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
var version: Long = oldVersion
// DynamicRealm exposes an editable schema
val schema: RealmSchema = realm.schema
// Changes from version 0 to 1: Adding lastName.
// All properties will be initialized with the default value "".
if (version == 0L) {
schema.get("Person")!!
.addField("lastName", String::class.java, FieldAttribute.REQUIRED)
version++
}
// Changes from version 1 to 2: Combining firstName/lastName into fullName
if (version == 1L) {
schema.get("Person")!!
.addField("fullName", String::class.java, FieldAttribute.REQUIRED)
.transform { obj: DynamicRealmObject ->
val name = "${obj.getString("firstName")} ${obj.getString("lastName")}"
obj.setString("fullName", name)
}
.removeField("firstName")
.removeField("lastName")
version++
}
// Changes from version 2 to 3: Replace age with birthday
if (version == 2L) {
schema.get("Person")!!
.addField("birthday", Date::class.java, FieldAttribute.REQUIRED)
.transform { obj: DynamicRealmObject ->
var birthYear = Date().year - obj.getInt("age")
obj.setDate("birthday", Date(birthYear, 1, 1))
}
.removeField("age")
version++
}
}
}
@RealmModule(classes = { Person::class.java })
class Module
val config = RealmConfiguration.Builder()
.schemaVersion(3) // Must be bumped when the schema changes
.migration(migration) // Migration to run instead of throwing an exception
.build()

You can make changes to the schema of a synchronized realm by modifying the JSON Schema defined in your application's backend. Synchronized realms do not require migration functions, since breaking changes to synchronized schemas cause synchronization errors. Sync handles non-breaking changes to synchronized realm schemas automatically. As a result, both old versions of your schema and new versions can synchronize as users upgrade their applications.

To learn more about schema changes to synchronized realms, see synced schema changes.

Note

Development Mode: Only for Defining Your Initial Schema

You can define the first version of your application's synced schema using Development Mode, which automatically translates client models into JSON Schema on the backend. However, you should make subsequent changes to your schema through edits to the JSON Schema in your App.

Tip

You can use the RealmConfiguration.shouldDeleteRealmIfMigrationNeeded() builder method when constructing a realm to delete the realm instead of performing a migration when a migration is required. This can come in handy during development when schemas often change.

Back

Relationships