0
0

More than 3 years have passed since last update.

【Realm】relationship と insert

Last updated at Posted at 2021-09-04

realm-java 10.8.0

RealmObject 派生オブジェクトが他の RealmObject 派生オブジェクトの参照を持つ場合、
参照元のオブジェクトを insert (もしくは update)すると参照先のオブジェクトも insert(update)される。

例えば次のようなクラスが定義されている場合を考える。

import io.realm.Realm
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where

open class To(
    @PrimaryKey
    var id: Int,
    var name: String,
) : RealmObject() {
    constructor() : this(0, "")

    override fun toString(): String = name
}

open class From(
    @PrimaryKey
    var id: Int,
    var name: String,
    var to: To? = null,
) : RealmObject() {
    constructor() : this(0, "")

    override fun toString(): String = name
}

次のように to1 オブジェクトを参照する from1 オブジェクトを insert すると、to1 も insert される。

val realm = Realm.getDefaultInstance()

val to1 = To(1, "to1")
val from1 = From(1, "from1", to1) // to1 の参照を持つ。

realm.executeTransaction { transactionRealm ->
    // from1 だけを insert する。
    transactionRealm.insert(from1)
}

realm.where<To>().findAll().also {
    // to1 も insert されていることを確認する。
    println(it) // > [to1]
}

また次のように to1_1 オブジェクトが insert 済みの状態で、主キーの値が to1_1 と同じであるオブジェクト to1_2 を参照する from1insertOrUpdate すると、to1_1to1_2 に更新される。

val realm = Realm.getDefaultInstance()

val to1_1 = To(1, "to1_1")
val to1_2 = To(1, "to1_2") // 主キー(id)の値が to1_1 と同じ。
val from1 = From(1, "from1", to1_2) // to1_2 の参照を持つ。

realm.executeTransaction { transactionRealm ->
    // to1_1 と from1 を insert/update する。to1_2 はしない。
    transactionRealm.insert(to1_1)
    transactionRealm.insertOrUpdate(from1)
}

realm.where<To>().findAll().also {
    // to1_1 は存在せず to1_2 だけが存在することを確認する。
    println(it) // > [to1_2]
}

なお次のように from1insertOrUpdate ではなく insert すると、例外がスローされる。

val realm = Realm.getDefaultInstance()

val to1_1 = To(1, "to1_1")
val to1_2 = To(1, "to1_2") // 主キー(id)の値が to1_1 と同じ。
val from1 = From(1, "from1", to1_2) // to1_2 の参照を持つ。

realm.executeTransaction { transactionRealm ->
    // to1_1 を insert する。
    transactionRealm.insert(to1_1)
    try {
        // from1 を insertOrUpdate ではなく insert する。
        transactionRealm.insert(from1)
    } catch (e: Throwable) {
        // 例外がスローされることを確認する。
        println(e) // > io.realm.exceptions.RealmPrimaryKeyConstraintException: Value already exists: 1
    }
}

/以上

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0