Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /
Read & Write Data

Crear objetos de dominio - SDK de Kotlin

Esta página describe los conceptos de transacciones de escritura y objetos gestionados en un Realm, y luego explica cómo crear y guardar un nuevo objeto en un Realm local o sincronizado utilizando el Kotlin SDK. Para aprender más sobre los objetos Realm y cómo definirlos, consulte Objetos Realm.

You can create objects whose object type is included in the realm schema when you open the realm. For more information, refer to Open a Realm or Open a Synced Realm.

Nota

Write to a Synced Realm

The syntax to write a new object to a realm is the same for a local or a synced realm. However, there are additional considerations that determine whether the write operation in a synced realm is successful. For more information, refer to Write Data to a Synced Realm - Kotlin SDK.

Realm handles writes in terms of transactions. All writes must happen within a transaction. A transaction is a list of read and write operations that Realm treats as a single indivisible operation: either all of the operations succeed or none of the operations in the transaction take effect.

Realm representa cada transacción como una función de devolución de llamada que contiene cero o más operaciones de lectura y escritura. Para ejecutar una transacción, se define una devolución de llamada de transacción y se pasa al dominio. Método write() o writeBlocking(). Con esta devolución de llamada, puede acceder a una instancia de MutableRealm y luego crear, leer, actualizar y eliminar objetos dentro del dominio. El dominio mutable representa el estado de escritura de un archivo de dominio. Los dominios mutables se proporcionan y administran automáticamente a través de realm.write o los métodos realm.writeBlocking.

Un realm solo permite una transacción de escritura abierta a la vez. Realm bloquea otras operaciones de guardar en otros hilos hasta que la transacción abierta en el realm mutable se completa. Por lo tanto, no hay condición de competencia al leer valores desde el realm dentro de una transacción.

When you are done with your transaction, Realm either commits it or cancels it:

  • When Realm commits a transaction, Realm writes all changes to disk. For synced realms, the SDK queues the change for synchronization with the backend.

  • When Realm cancels a write transaction or an operation in the transaction causes an error, all changes are discarded.

Nota

Frozen Objects

Los objetos devueltos por un cierre de escritura se convierten en objetos congelados cuando se completa la transacción de escritura. Para más información, consulta Arquitectura congelada - Kotlin SDK.

Realm APIs may refer to objects as managed or unmanaged. When you create a Realm object with the Kotlin SDK, it is unmanaged until it is copied to a realm, which creates a managed instance.

  • Managed objects are Realm objects that persist in a realm. Managed objects can only be accessed from an open realm. They can be updated with changes within write transactions as long as that realm remains open. Managed objects are tied to the realm instance from which they originated and cannot be written to another realm.

    Puedes usar las API de Realm con objetos gestionados. Por ejemplo, los objetos gestionados pueden tener relaciones con otros objetos y ser observados para detectar cambios. También se puede crear una copia no gestionada de un objeto gestionado. Consulta la sección Crear una copia no gestionada de un objeto Realm o colección en esta página.

  • Unmanaged objects are instances of Realm objects that behave like normal Kotlin objects, but they are not persisted in a realm. All Realm objects are unmanaged until you copy them to a realm within a write transaction. You cannot use Realm APIs with unmanaged objects or observe them for changes.

Tip

Puedes comprobar si un objeto está administrado con el método isManaged().

Before you can create a new object and persist it to the realm, you must Define a New Object Type. Then, you include that object type in your realm schema when you open the realm.

Importante

Object Types Must Be in Your Schema

Solo se pueden guardar objetos cuyo tipo de objeto Realm está incluido en el esquema realm. Si intentas hacer referencia o guardar un objeto de un tipo de objeto Realm que no está en tu esquema, Realm devolverá un error de validación de esquema.

To create a new object and persist it to the realm:

  1. Abra una transacción de escritura con realm.write() o realm.writeBlocking().

  2. Cree una instancia de un objeto no administrado con el constructor de la clase. Puede usar un bloque de aplicación. para configurar múltiples propiedades a la vez.

  3. Pass the unmanaged object instance to copyToRealm() to persist the object data to the realm. This method returns a live managed instance of the object.

    Importante

    Asymmetric Objects Use Insert()

    Los objetos asimétricos son objetos especiales de solo escritura que no persisten en el dominio. No copyToRealm() usan. En su lugar, se pasa la instancia del objeto asimétrico al insert() método de extensión dentro de una transacción de escritura. Consulte la sección "Crear un objeto asimétrico" en esta página para obtener más información.

  4. Work with the persisted Realm object through the returned instance. The live object is accessible until the write transaction completes. Note that this does not apply to asymmetric objects, which are write-only and do not persist to the realm.

También puedes hacer una inserción en un realm utilizando criterios específicos. Para obtener más información, consulta inserción de un objeto Realm.

Para crear una nueva instancia de RealmObject, crea un nuevo objeto de tipo de objeto realm.

In the following example, we instantiate a Frog object in a realm.write() block, then pass the instantiated object to copyToRealm() to return a managed instance:

// Open a write transaction
realm.write {
// Instantiate a new unmanaged Frog object
val unmanagedFrog = Frog().apply {
name = "Kermit"
age = 42
owner = "Jim Henson"
}
assertFalse(unmanagedFrog.isManaged())
// Copy the object to realm to return a managed instance
val managedFrog = copyToRealm(unmanagedFrog)
assertTrue(managedFrog.isManaged())
// Work with the managed object ...
}

Para crear una nueva instancia de EmbeddedRealmObject, asigna una instancia de un tipo de objeto incrustado a una propiedad del objeto principal. Esto puede darse en una relación uno a uno, uno a muchos, o inversa, dependiendo de cómo se haya definido el objeto incrustado dentro del tipo de objeto Realm. Para obtener más información, consulta Definir un objeto incrustado.

Nota

Los objetos incrustados deben crearse dentro de un objeto padre

An embedded object requires a parent object and cannot exist as an independent Realm object.

Los objetos incrustados tienen propiedad estricta con su objeto principal. Después de crear el objeto incrustado,no se puede reasignar a otro objeto principal ni compartirlo entre varios objetos principales.

En el siguiente ejemplo, instanciamos un nuevo objeto Contact con un Address incrustado, que contiene un objeto Contact y un objeto Country incrustado:

realm.write {
// Instantiate a parent object with one embedded address
val contact = Contact().apply {
name = "Kermit"
address = EmbeddedAddress().apply {
propertyOwner = Contact().apply { name = "Mr. Frog" }
street = "123 Pond St"
country = EmbeddedCountry().apply { name = "United States" }
}
}
// Copy all objects to the realm to return managed instances
copyToRealm(contact)
}

We also instantiate a new Business object with a list of embedded Address objects, which also contain Contact objects and embedded Country objects:

realm.write {
// Instantiate a parent object with multiple embedded addresses
val localOffice = EmbeddedAddress().apply {
propertyOwner = Contact().apply { name = "Michigan J. Frog" }
street = "456 Lily Pad Ln"
country = EmbeddedCountry().apply { name = "United States" }
}
val remoteOffice = EmbeddedAddress().apply {
propertyOwner = Contact().apply { name = "Mr. Toad" }
street = "789 Leaping Frog Ave"
country = EmbeddedCountry().apply { name = "Ireland" }
}
val business = Business().apply {
name = "Big Frog Corp."
addresses = realmListOf(localOffice, remoteOffice)
}
// Copy all objects to the realm to return managed instances
copyToRealm(business)
}

Novedades en la versión 1.10.0.

Unlike other Realm objects, you do not use the copyToRealm() method to create it. This is because asymmetric objects are write-only: they are not persisted to the realm. Instead, you use a special insert() extension method to insert it into the realm.

To create a new AsymmetricRealmObject instance, instantiate a new object of an asymmetric object type using insert().

In the following example, we instantiate a new WeatherSensor object and pass it to insert() within a write transaction:

// Open a write transaction
realm.write {
// Create a new asymmetric object
val weatherSensor = WeatherSensor().apply {
deviceId = "WX1278UIT"
temperatureInFarenheit = 6.7F
barometricPressureInHg = 29.65F
windSpeedInMph = 2
}
// Insert the object into the realm with the insert() extension method
insert(weatherSensor)
// WeatherSensor object is inserted into the realm, then synced to the
// App Services backend. You CANNOT access the object locally because it's
// deleted from the local realm after sync is complete.
}

Once inserted, the asymmetric object syncs to the App Services backend and the linked Atlas database. You cannot access the managed data locally, add it to or remove it from a realm, or query for it. For information on how to use asymmetric objects in your application, refer to Stream Data to Atlas - Kotlin SDK.

Depending on how you define your object type, you might have properties that are special Realm-specific types.

In the following example, we have a Frog object type with several Realm properties:

class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var birthdate: RealmInstant? = null
var fliesEaten: MutableRealmInt? = null
var favoriteThings: RealmList<RealmAny?> = realmListOf()
}

Para crear una nueva instancia de objeto con una propiedad RealmInstant, cree una instancia de un objeto y pase un valor inicial a la RealmInstant propiedad usando:

For more information about the RealmInstant type, refer to RealmInstant (Timestamp).

In the following example, we instantiate a new Frog object with a birthdate property and pass an initial value to RealmInstant.from():

realm.write {
// Instantiate a new unmanaged Frog object with a RealmInstant property
val frog = Frog().apply {
name = "Kermit"
// Set an initial value with RealmInstant.from() or RealmInstant.now()
birthdate = RealmInstant.from(1_577_996_800, 0)
}
// Copy the object to the realm to return a managed instance
copyToRealm(frog)
}

Para crear una nueva instancia de objeto con una propiedad MutableRealmInt, cree una instancia de un objeto y pase un valor inicial a la MutableRealmInt propiedad mediante MutableRealmInt.create(). Para obtener más información sobre el MutableRealmInt tipo, consulte MutableRealmInt (Counter).

In the following example, we instantiate a new Frog object with a fliesEaten property and pass an initial value to MutableRealmInt.create():

realm.write {
// Instantiate a new unmanaged Frog object with a MutableRealmInt property
val frog = Frog().apply {
name = "Michigan J. Frog"
// Set an initial value with MutableRealmInt.create()
fliesEaten = MutableRealmInt.create(200)
}
// Copy the object to the realm to return a managed instance
copyToRealm(frog)
}

Para crear una nueva instancia de objeto con una propiedad polimórfica RealmAny, instanciar un objeto y pasar un valor inicial de un tipo admitido en la propiedad RealmAny utilizando RealmAny.create(). Para obtener una lista de los tipos de valores que RealmAny puede contener, consulta RealmAny (Mixto).

En el siguiente ejemplo, se instancia un nuevo objeto Frog con una lista favoriteThings de tipo RealmAny y se pasan los valores iniciales a RealmAny.create():

realm.write {
// Instantiate a new unmanaged Frog object with a RealmAny property
val frog = Frog().apply {
name = "Kermit"
// Set initial values with RealmAny.create()
favoriteThings = realmListOf(
RealmAny.create(42),
RealmAny.create("rainbows"),
RealmAny.create(Frog().apply {
name = "Kermit Jr."
})
)
}
// Copy the object to the realm to return a managed instance
copyToRealm(frog)
}

Después de crear el objeto, debe conocer el tipo de valor almacenado para trabajar con la propiedad RealmAny. Para aprender cómo actualizar las propiedades RealmAny después de crear el objeto, consulta Actualiza una propiedad RealmAny (Mixta).

Depending on how you define your object type, you might have properties that are defined as one of the following supported Collection Types:

  • RealmList

  • RealmSet

  • RealmDictionary

Para obtener más información, consulte Definir propiedades de colección.

Collections are mutable: you can add and remove elements in a collection within a write transaction.

Las colecciones pueden contener objetos administrados y no administrados. Al copiar una colección al dominio, se crea una instancia administrada de la colección y de todos sus elementos, incluidos los no administrados. Las colecciones no administradas se comportan como sus clases Kotlin correspondientes y no se persisten en el dominio.

Tip

Listen for Changes to a Created Collection

After you create a collection, you can register a notification handler to listen for changes. For more information, refer to Register a Collection Change Listener.

Para crear una nueva instancia de objeto con una propiedad RealmList, cree una instancia de un objeto y pase cualquier valor de un tipo compatible a la RealmList propiedad. Para obtener una lista de los tipos de valores que RealmList puede contener, consulte RealmList.

Puedes instanciar una lista no gestionada con realmListOf() o pasar elementos a la lista usando list.add(), list.addAll(), o list.set(). La lista no está gestionada hasta que se copia en el realm.

En el siguiente ejemplo, instanciamos un nuevo objeto Frog con valores iniciales para varias propiedades RealmList:

realm.write {
// Instantiate a new unmanaged Frog object with a RealmList property
val frog = Frog().apply {
name = "Kermit"
// Set values for each unmanaged list
favoritePonds.addAll(realmListOf(
Pond().apply { name = "Picnic Pond" },
Pond().apply { name = "Big Pond" }
))
favoriteForests.add(EmbeddedForest().apply { name = "Hundred Acre Wood" })
favoriteWeather = realmListOf("rain", "snow")
}
// Copy all objects to the realm to return managed instances
copyToRealm(frog)
}

To create a new object instance with a RealmSet property, instantiate an object and pass any values of a supported type to the RealmSet property. For a list of valid types that RealmSet can hold, refer to RealmSet.

Puedes instanciar un conjunto no administrado con realmSetOf() o pasarle elementos mediante set.add() o set.addAll(). El conjunto no se administra hasta que lo copies al dominio.

En el siguiente ejemplo, se instancia un nuevo objeto Frog con valores iniciales para las propiedades establecidas favoriteSnacks y favoriteWeather:

realm.write {
// Instantiate a new unmanaged Frog object with RealmSet properties
val frog = Frog().apply {
name = "Kermit"
// Set initial values to each unmanaged set
favoriteSnacks.addAll(setOf(
Snack().apply { name = "flies" },
Snack().apply { name = "crickets" },
Snack().apply { name = "worms" }
))
favoriteWeather.add("rain")
}
// Copy all objects to the realm to return managed instances
copyToRealm(frog)
}

Para crear una nueva instancia de objeto con una propiedad RealmDictionary, cree una instancia de un objeto y pase cualquier par clave-valor de un tipo compatible a la RealmDictionary propiedad. RealmDictionary solo acepta una String clave, pero los valores pueden ser de tipos distintos de cadenas. Para obtener una lista de tipos válidos, consulte RealmMap/RealmDictionary.

Puedes instanciar un diccionario no administrado con realmDictionaryOf() o realmDictionaryEntryOf(). También puedes pasar valores clave con put() o putAll(). El diccionario no se administra hasta que lo copies al dominio.

In the following example, we instantiate a new Frog object with initial key-values for several dictionary properties:

realm.write {
val frog = Frog().apply {
name = "Kermit"
// Set initial key-values to each unmanaged dictionary
favoriteFriendsByPond = realmDictionaryOf(
"Picnic Pond" to Frog().apply { name = "Froggy Jay" },
"Big Pond" to Frog().apply { name = "Mr. Toad" }
)
favoriteTreesInForest["Maple"] = EmbeddedForest().apply {
name = "Hundred Acre Wood"
}
favoritePondsByForest.putAll(
mapOf(
"Silver Pond" to "Big Forest",
"Big Lake" to "Elm Wood",
"Trout Pond" to "Sunny Wood"
)
)
}
// Copy all objects to the realm to return managed instances
copyToRealm(frog)
}

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"

Depending on how you define your object type, you might have properties that reference another Realm object. This can be a to-one, to-many, or inverse relationship. For more information on defining relationships in your object model, refer to Define a Relationship.

También puedes incrustar un objeto Realm directamente dentro de otro para crear una estructura de datos anidada con un tipo EmbeddedRealmObject. Para crear una relación con un objeto incrustado, consulta la sección Crear un objeto incrustado en esta página.

Para crear una nueva instancia de objeto con una propiedad de relación de uno a uno, cree una instancia de ambos objetos y pase el objeto referenciado a la propiedad de relación.

En el siguiente ejemplo, instanciamos un nuevo objeto Frog con una propiedad favoritePond que referencia un objeto Pond y una propiedad bestFriend que referencia otro objeto Frog:

realm.write {
// Instantiate a new unmanaged Frog object with to-one
// relationship with a Realm object
val frog = Frog().apply {
name = "Kermit"
age = 12
favoritePond = Pond().apply { name = "Picnic Pond" }
bestFriend = Frog().apply { name = "Froggy Jay" }
}
// Copy all objects to the realm to return managed instances
copyToRealm(frog)
}

To create a new object instance with a to-many relationship property, instantiate all objects and pass any referenced objects to the relationship collection property.

En el siguiente ejemplo, instanciamos un nuevo objeto Forest con una propiedad frogsThatLiveHere que hace referencia a un conjunto de Frog objetos y una propiedad nearByPonds que hace referencia a una lista de Pond objetos:

realm.write {
// Instantiate a new unmanaged Forest object with to-many
// relationship with multiple Realm objects
val forest = Forest().apply {
name = "Froggy Forest"
frogsThatLiveHere = realmSetOf(
Frog().apply { name = "Kermit" },
Frog().apply { name = "Froggy Jay" }
)
nearbyPonds = realmListOf(
Pond().apply { name = "Small Picnic Pond" },
Pond().apply { name = "Big Pond" }
)
}
// Copy all objects to the realm to return managed instances
copyToRealm(forest)
}

To create a new object instance with an inverse relationship property, instantiate the parent object and pass any referenced child objects to the backlink collection property.

En el siguiente ejemplo, se instanciará un objeto User nuevo con una propiedad de vínculos inversos posts que hace referencia a una lista de objetos Post:

realm.write {
// Instantiate a new unmanaged User object with to-many
// relationship with multiple Realm objects
val post1 = Post().apply {
title = "Forest Life"
}
val post2 = Post().apply {
title = "Top Ponds of the Year!"
}
val user = User().apply {
name = "Kermit"
posts = realmListOf(post1, post2)
}
// Copy all objects to the realm to return managed instances
copyToRealm(user)
}

After you create the object, you can access the backlinks collection property to get the child objects, but you cannot directly modify the backlink itself. For more information, refer to Update an Inverse Relationship.

Puede crear una copia no administrada de un objeto o colección administrados pasándola a copyFromRealm(). Este método devuelve una copia no administrada en memoria del objeto o colección. Para las colecciones, se trata de una copia profunda que incluye todos los objetos referenciados hasta el depth especificado.

In the following example, we create an unmanaged copy of an existing managed Pond object that contains a list of two Frog objects. After copying the object from the realm, we confirm that the copy is unmanaged and contains both referenced Frog objects:

realm.writeBlocking {
// Fetch the managed object you want to copy
val managedPond = query<Pond>("name == $0", "Big Pond").find().first()
assertTrue(managedPond.isManaged())
// Create an unmanaged copy of the object
val unmanagedPond = copyFromRealm(managedPond)
assertFalse(unmanagedPond.isManaged())
Log.v("Unmanaged pond name: ${unmanagedPond.name}")
// Confirm the unmanaged copy contains all elements
// in the copied object's RealmList
val unmanagedFrogs = unmanagedPond.frogsThatLiveHere
assertFalse(unmanagedFrogs[0].isManaged())
assertFalse(unmanagedFrogs[1].isManaged())
assertEquals(2, unmanagedFrogs.size)
Log.v("Unmanaged frogs: ${unmanagedFrogs[0].name}, ${unmanagedFrogs[1].name}")
}
Unmanaged pond name: Big Pond
Unmanaged frogs: Kermit, Froggy Jay

Volver

Read & Write Data