Navigation

Define a Realm Object Schema - Android SDK

Tip

For conceptual information about schemas, as well as details about types and constraints, see Fundametals: Object Models & Schemas.

To define a Realm object in your application, create a subclass of RealmObject or implement RealmModel.

Important

All Realm objects must provide an empty constructor.

Example

The following code block shows a Realm object that describes a Frog. This Frog class can be stored in Realm Database because it extends the RealmObject class.

import io.realm.RealmObject
// providing default values for each constructor parameter
// fulfills the need for an empty constructor
open class Frog(
var name: String? = null,
var age: Int = 0,
var species: String? = null,
var owner: String? = null
) : RealmObject() // To add an object to your Realm Schema, extend RealmObject
Important

All Realm objects defined must use the open visibility modifier.

Example

The following code block shows a Realm object that describes a Frog. This Frog class can be stored in Realm Database because it implements the RealmModel class and uses the @RealmClass annotation:

import io.realm.RealmModel
import io.realm.annotations.RealmClass
@RealmClass
open class Frog : RealmModel {
var name: String? = null
var age = 0
var species: String? = null
var owner: String? = null
constructor(name: String?, age: Int, species: String?, owner: String?) {
this.name = name
this.age = age
this.species = species
this.owner = owner
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}
Important

All Realm objects must use the open visibility modifier.

Tip
Using RealmObject Methods

When you create a Realm object by extending the RealmObject class, you can access RealmObject class methods dynamically on instances of your Realm object. Realm objects created by implementing RealmModel can access those same methods statically through the RealmObject class:

// With RealmObject
frogRealmObject?.isValid
frogRealmObject?.addChangeListener(listener)
// With RealmModel
RealmObject.isValid(frogRealmModel)
RealmObject.addChangeListener(frogRealmModel, listener)

Realm objects can contain lists of non-Realm-object data types:

import io.realm.RealmList
import io.realm.RealmObject
open class Frog : RealmObject {
var name: String? = null
var age = 0
var species: String? = null
var owner: String? = null
var favoriteColors : RealmList<String>? = null
constructor(
name: String?,
age: Int,
species: String?,
owner: String?,
favoriteColors: RealmList<String>?
) {
this.name = name
this.age = age
this.species = species
this.owner = owner
this.favoriteColors = favoriteColors
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}
Tip

To set up a many-to-one or one-to-one relationship, create a field whose type is a Realm object in your application:

import io.realm.RealmObject
open class Frog : RealmObject {
var name: String? = null
var age = 0
var species: String? = null
var owner: String? = null
var bestFriend: Frog? = null
constructor(
name: String?,
age: Int,
species: String?,
owner: String?,
bestFriend: Frog?
) {
this.name = name
this.age = age
this.species = species
this.owner = owner
this.bestFriend = bestFriend
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}

Each Frog references either zero Frog instances or one other Frog instance. Nothing prevents multiple Frog instances from referencing the same Frog as a best friend; the distinction between a many-to-one and a one-to-one relationship is up to your application.

import io.realm.RealmList
import io.realm.RealmObject
open class Frog : RealmObject {
var name: String? = null
var age = 0
var species: String? = null
var owner: String? = null
var bestFriends: RealmList<Frog>? = null
constructor(
name: String?,
age: Int,
species: String?,
owner: String?,
bestFriends: RealmList<Frog>?
) {
this.name = name
this.age = age
this.species = species
this.owner = owner
this.bestFriends = bestFriends
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}

RealmList s are containers of RealmObject s, but otherwise behave like a regular collection. You can use the same object in multiple RealmList s.

By default, Realm Database relationships are unidirectional. You can follow a link from one class to a referenced class, but not in the opposite direction. Consider the following class defining a Toad with a list of frogFriends:

import io.realm.RealmList
import io.realm.RealmObject
open class Toad : RealmObject {
var frogFriends: RealmList<Frog>? = null
constructor(frogFriends: RealmList<Frog>?) {
this.frogFriends = frogFriends
}
constructor() {}
}

You can provide a link in the opposite direction, from Frog to Toad, with the @LinkingObjects annotation on a final (in Java) or val (in Kotlin) field of type RealmResults<T>:

import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.annotations.LinkingObjects
open class Frog : RealmObject {
var name: String? = null
var age = 0
var species: String? = null
var owner: String? = null
@LinkingObjects("frogFriends")
private val toadFriends: RealmResults<Toad>? = null
constructor(name: String?, age: Int, species: String?, owner: String?) {
this.name = name
this.age = age
this.species = species
this.owner = owner
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}
Important

Inverse relationship fields must be marked final.

Realm Database provides the ability to nest objects within other objects. This has several advantages:

  • If using Realm Sync, objects will translate into MongoDB documents that follow a denormalized data model.
  • When you delete an object that contains another object, the delete operation removes both objects from the realm, so unused objects don't accumulate in your realm file, taking up valuable space on user's mobile devices.

To embed an object, set the embedded property of the @RealmClass annotation to true on the class that you'd like to nest within another class:

import io.realm.RealmObject
import io.realm.annotations.RealmClass
@RealmClass(embedded = true)
open class Fly : RealmObject {
private var name: String? = null
constructor(name: String?) {
this.name = name
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}

Then, any time you reference that class from another class, Realm Database will embed the referenced class within the enclosing class, as in the following example:

import io.realm.RealmObject
open class Frog : RealmObject {
var name: String? = null
var age = 0
var species: String? = null
var owner: String? = null
var lastMeal: Fly? = null
constructor(
name: String?,
age: Int,
species: String?,
owner: String?,
lastMeal: Fly?
) {
this.name = name
this.age = age
this.species = species
this.owner = owner
this.lastMeal = lastMeal
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}

Use annotations to customize your Realm object models.

You may optionally define a primary key for an object type as part of the object schema with the @PrimaryKey annotation:

import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
open class Frog : RealmObject {
@PrimaryKey var name : String? = null
var age = 0
var species: String? = null
var owner: String? = null
constructor(name: String?, age: Int, species: String?, owner: String?) {
this.name = name
this.age = age
this.species = species
this.owner = owner
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}

Only one field in a RealmObject can use the @PrimaryKey annotation.

import io.realm.RealmObject
import io.realm.annotations.Required
open class Frog : RealmObject {
@Required var name: String? = null
var age = 0
var species: String? = null
var owner: String? = null
constructor(name: String?, age: Int, species: String?, owner: String?) {
this.name = name
this.age = age
this.species = species
this.owner = owner
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}

Fields are only optional if they can hold a value of null and they are not marked with the Required annotation.

To assign a default value to a field, use the built-in language features to assign default values.

Assign default values in the field declaration:

import io.realm.RealmObject
open class Frog : RealmObject {
var name = "Kitty"
var age = 0
var species: String? = null
var owner: String? = null
constructor(name: String, age: Int, species: String?, owner: String?) {
this.name = name
this.age = age
this.species = species
this.owner = owner
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}
Note
Default Values and Nullability

While default values ensure that a newly created object cannot contain a value of null (unless you specify a default value of null), they do not impact the nullability of a field. To make a field non-nullable, see Required Fields.

To index a field, use the @Index annotation:

import io.realm.RealmObject
import io.realm.annotations.Index
open class Frog : RealmObject {
var name: String? = null
var age = 0
@Index var species : String? = null
var owner: String? = null
constructor(name: String?, age: Int, species: String?, owner: String?) {
this.name = name
this.age = age
this.species = species
this.owner = owner
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}

If you don't want to save a field in your model to a realm, you can ignore a field.

Ignore a field from a Realm object model with the @Ignore annotation:

import io.realm.RealmObject
import io.realm.annotations.Ignore
open class Frog : RealmObject {
var name: String? = null
var age = 0
var species: String? = null
// can you ever really own a frog persistently?
@Ignore var owner : String? = null
constructor(name: String?, age: Int, species: String?, owner: String?) {
this.name = name
this.age = age
this.species = species
this.owner = owner
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}
Note
Ignoring static and transient Fields

Fields marked static or transient are always ignored, and do not need the @Ignore annotation.

By default, Realm Database uses the name defined in the model class to represent fields internally. In some cases you might want to change this behavior:

  • To make it easier to work across platforms, since naming conventions differ.
  • To change a field name in Kotlin without forcing a migration.

Choosing an internal name that differs from the name used in model classes has the following implications:

  • Migrations must use the internal name when creating classes and fields.
  • Schema errors reported will use the internal name.

Use the @RealmField annotation to rename a field:

import io.realm.RealmObject
import io.realm.annotations.RealmField
open class Frog : RealmObject {
var name: String? = null
var age = 0
@RealmField("latinName") var species: String? = null
var owner: String? = null
constructor(name: String?, age: Int, species: String?, owner: String?) {
this.name = name
this.age = age
this.species = species
this.owner = owner
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}

Alternatively, you can also assign a naming policy at the module or class levels to change the way that Realm Database interprets field names.

You can define a naming policy at the module level, which will affect all classes included in the module:

import io.realm.annotations.RealmModule
import io.realm.annotations.RealmNamingPolicy
@RealmModule( allClasses = true, classNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES, fieldNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES )
open class MyModule

You can also define a naming policy at the class level, which overrides module level settings:

import io.realm.RealmObject
import io.realm.annotations.RealmClass
import io.realm.annotations.RealmNamingPolicy
@RealmClass(fieldNamingPolicy = RealmNamingPolicy.PASCAL_CASE)
open class Frog : RealmObject {
var name: String? = null
var age = 0
var species: String? = null
var owner: String? = null
constructor(name: String?, age: Int, species: String?, owner: String?) {
this.name = name
this.age = age
this.species = species
this.owner = owner
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}

By default, Realm Database uses the name defined in the model class to represent classes internally. In some cases you might want to change this behavior:

  • To support multiple model classes with the same simple name in different packages.
  • To make it easier to work across platforms, since naming conventions differ.
  • To use a class name that is longer than the 57 character limit enforced by Realm Database.
  • To change a class name in Kotlin without forcing a migration.

Use the @RealmClass annotation to rename a class:

import io.realm.RealmObject
import io.realm.annotations.RealmClass
@RealmClass(name = "Short_Bodied_Tailless_Amphibian")
open class Frog : RealmObject {
var name: String? = null
var age = 0
var species: String? = null
var owner: String? = null
constructor(name: String?, age: Int, species: String?, owner: String?) {
this.name = name
this.age = age
this.species = species
this.owner = owner
}
constructor() {} // RealmObject subclasses must provide an empty constructor
}

By default, your application's Realm Schema includes all classes that extend RealmObject. If you only want to include a subset of classes that extend RealmObject in your Realm Schema, you can include that subset of classes in a module and open your realm using that module:

import io.realm.annotations.RealmModule
@RealmModule(classes = [Frog::class, Fly::class])
open class MyModule
Give Feedback