Define a Realm Object Model - Kotlin SDK
On this page
- Object Types & Schemas
- Realm Schema
- Property Types
- Property Annotations
- Define a New Object Type
- Define a Relationship Property
- Define an Inverse Relationship Property
- Define a Collection
- Define a RealmSet
- Define a RealmDictionary/RealmMap
- Define an Embedded Object
- Define an Asymmetric Object
- Unsupported Kotlin Language Features
- Data Classes
- Inheritance
- Single Primary Constructor
The Kotlin SDK memory maps Realm objects directly to native Kotlin objects, so there's no need to use a special data access library. You define your application's data model via regular Kotlin classes declared in your application code object.
To learn about how to make changes to your Realm objects after defining your Realm object model, refer to Change an Object Model.
Object Types & Schemas
Realm objects are regular Kotlin classes, and you can work with them as you would any other class instance.
Every Realm object has an object type that refers to the object's class.
Objects of the same type share an object schema, which defines the properties and relationships for objects of that type.
You define object schemas by using Kotlin class declarations.
Example
The following schema defines a Car
object type with
make
, model
, and miles
properties:
class Car : RealmObject { var make: String = "" var model: String = "" var miles: Int = 0 }
Realm Schema
A realm schema is a list of valid object schemas that a realm may contain. Every Realm object must conform to an object type that's included in its realm's schema.
If a realm already contains data when you open it, Realm validates each object to ensure that an object schema was provided for its type and that it meets all of the constraints specified in the schema.
Property Types
The Kotlin SDK supports Kotlin data types, a limited subset of BSON types, UUID, and Realm-specific types.
To learn more about the available property types, refer to the Supported Types page.
Property Annotations
Annotations add functionality to properties in your Realm object models. You can use annotations for things like marking a property as nullable, setting a primary key, ignoring a property, and more.
To learn more about the available property annotations, refer to Property Annotations.
Define a New Object Type
To define a Realm object type:
Create a uniquely named Kotlin class that implements the RealmObject interface.
Add fields to your class. You can add any supported data types as a field in your class.
Add any property annotations to give Realm additional information about a property, including whether Realm should ignore the property or should be indexed.
// Defines a `Cat` object type // with several properties class Cat : RealmObject { var name: String = "" var color: String? = null var age: Int = 0 }
Note
Class names are limited to a maximum of 57 UTF-8 characters.
Once you've defined your object model, you can pass the class to the schema
property of the
RealmConfiguration
when you open the realm.
val config = RealmConfiguration.Builder( schema = setOf(Cat::class) // Pass the defined class as the object schema ) .build() val realm = Realm.open(config)
Define a Relationship Property
You can define relationships between Realm objects in your schema. The Realm Kotlin SDK supports to-one relationships, to-many relationships, inverse relationships, and embedding objects within other objects.
For more information, refer to the Relationships page.
Define an Inverse Relationship Property
You can define a backlink property as a BacklinksDelegate
or EmbeddedBacklinksDelegate
to the parent object using the backlinks()
method.
A
BacklinksDelegate<T>
property is defined as a RealmResults list of the parentRealmObject
type:val child: RealmResults<ParentObjectType> by backlinks(ParentObjectType::children) An
EmbeddedBacklinksDelegate<T>
property is defined as the parentRealmObject
type:val embeddedChild: ParentObjectType by backlinks(ParentObjectType::embeddedChildren)
You then reference the backlinks in collections in the parent RealmObject
:
var children: RealmSet<ChildObjectType> = realmSetOf() var embeddedChildren: RealmList<EmbeddedChildType> = realmListOf() // RealmSets cannot contain embedded objects var embeddedChildrenDictionary: RealmDictionary<EmbeddedChildType?> = realmDictionaryOf()
Define a Collection
You can define collections of items using
RealmList
, RealmSet
, and RealmDictionary
types.
For more information on the collection types used in the Kotlin SDK, refer to Collection Types.
Define a RealmSet
To define a property as a RealmSet, specify its
type within the schema as RealmSet<T>
, where T is any of the supported
data types or a
RealmObject.
If a RealmSet
's value is a RealmObject
, the value cannot have
null elements.
Instantiate an unmanaged RealmSet
by setting the field's default value
using the
realmSetOf()
method.
In the following example, we define a Frog
schema with a
favoriteSnacks
field that is a RealmSet
of Snack
objects:
class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" var favoriteSnacks: RealmSet<Snack> = realmSetOf() } class Snack : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" }
Define a RealmDictionary/RealmMap
To define a RealmDictionary, specify its type
within the schema as RealmDictionary<T>
, where T is any Realm primitive type, a RealmObject
, or an EmbeddedRealmObject
.
If a RealmDictionary
's value is a RealmObject
or EmbeddedRealmObject
, the value must be declared nullable.
class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" var favoritePondsByForest: RealmDictionary<String> = realmDictionaryOf() }
Realm disallows the use of .
or $
characters in map keys.
You can use percent encoding and decoding to store a map key that contains
one of these disallowed characters.
// Percent encode . or $ characters to use them in map keys val mapKey = "Hundred Acre Wood.Northeast" val encodedMapKey = "Hundred Acre Wood%2ENortheast"
Define an Embedded Object
To define an embedded object, derive a class from EmbeddedRealmObject:
// Define an embedded object (cannot have primary key) class Address() : EmbeddedRealmObject { var street: String? = null var city: String? = null var state: String? = null var postalCode: String? = null } // Define an object containing one embedded object class Contact : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // Embed a single object (must be optional) var address: Address? = null } // Define an object containing an array of embedded objects class Business : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // Embed an array of objects (cannot be null) var addresses: RealmList<Address> = realmListOf() }
Once your embedded object class is defined, you must include its schema in the realm's configuration to use it in your realm instance:
// Include parent and embedded object classes in schema val config = RealmConfiguration.Builder( setOf(Contact::class, Address::class) ) .build() val realm = Realm.open(config)
Define an Asymmetric Object
New in version 1.10.0.
If your app uses Flexible Sync, you can use Data Ingest to sync an object unidirectionally from your device to the database linked to your Atlas App Services App. Define an asymmetric object by implementing the AsymmetricRealmObject interface:
class WeatherSensor : AsymmetricRealmObject { var id: ObjectId = ObjectId() var deviceId: String = "" var temperatureInFarenheit: Float = 0.0F var barometricPressureInHg: Float = 0.0F var windSpeedInMph: Int = 0 }
An asymmetric object is an insert-only object. You can create an asymmetric object, which then syncs unidirectionally to the Atlas database linked to your App with Device Sync. Realm deletes this object after syncing. You cannot read, update, or delete an asymmetric object from the realm.
For more information on how asymmetric objects function, see Asymmetric Objects.
Unsupported Kotlin Language Features
The Realm Kotlin SDK does not support or provides only limited support for the following Kotlin language features:
Data Classes
The Realm Kotlin SDK does not support using data classes to model data. Typically, data classes are used for immutable data. This goes against how the Realm Kotlin SDK models data.
Inheritance
Realm Kotlin SDK classes may only inherit from
Realm Object types.
For example, your class may inherit from RealmObject
or
EmbeddedRealmObject
, but not from custom classes that do not implement
a Realm object interface.
// SUPPORTED // You can inherit from Realm Object types directly class MyBaseClass: RealmObject { var name: String = "" } // NOT SUPPORTED // You can not inherit from classes that implement Realm object types // This form of inheritance is not supported in the Realm Kotlin SDK class Person: MyBaseClass { var age: Int }
Single Primary Constructor
The Realm Kotlin SDK does not support having a single primary constructor. The SDK requires an empty constructor to create objects. As a workaround, you can do something similar to the following:
// SUPPORTED // Realm requires an empty constructor to create objects class Person(var name: String, var age: Int): RealmObject { constructor(): this("", 0) // Empty constructor required by Realm } // NOT SUPPORTED // The Realm Kotlin SDK does not support having a single primary constructor class Person(var name: String, var age: Int) RealmObject { }