Define a Realm Object Schema - Android SDK¶
For conceptual information about schemas, as well as details about types and constraints, see Fundametals: Object Models & Schemas.
Define a Realm Object¶
To define a Realm object in your application, create a subclass of RealmObject or implement RealmModel.
All Realm objects must provide an empty constructor.
Extend RealmObject
¶
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
All Realm objects defined must use the
open
visibility modifier.
Implement RealmModel
¶
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 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 }
All Realm objects must use the open
visibility modifier.
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)
Lists¶
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 }
Define a Relationship Field¶
Many-to-One¶
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.
Many-to-Many¶
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.
Inverse Relationships¶
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 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 }
Inverse relationship fields must be marked final
.
Define an Embedded Object Field¶
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 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 }
Annotations¶
Use annotations to customize your Realm object models.
Primary Key¶
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 { 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.
Required Fields¶
import io.realm.RealmObject import io.realm.annotations.Required 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 }
Optional Fields¶
Fields are only optional if they can hold a value of null
and they
are not marked with the Required
annotation.
Default Field Values¶
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 }
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.
Index a Field¶
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 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 }
Ignore a Field¶
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? 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 marked static
or transient
are always ignored, and do
not need the @Ignore
annotation.
Rename a Field¶
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 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 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 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 }
Rename a Class¶
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 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 }
Omit Classes from your Realm Schema¶
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 open class MyModule