realm / realm-java

Realm is a mobile database: a replacement for SQLite & ORMs
http://realm.io
Apache License 2.0
11.45k stars 1.75k forks source link

Add posibility to remove all nested objects #7782

Closed Kolyall closed 1 year ago

Kolyall commented 1 year ago

Problem

Version: android io.realm:realm-gradle-plugin:10.13.0

add posibility to override fun deleteFromRealm, then I will add my implementation of deleting the parent object like this:

override fun deleteFromRealm() {
        childs?.deleteAllFromRealm()
        super,deleteFromRealm()
    }

I have: RParent:

open class RParent constructor(
    @PrimaryKey
    @Required
    var id: String = "",
    var childs: RealmList<RChild>? = null
) : RealmObject() {

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as RParent

        if (id != other.id) return false

        return true
    }

    override fun hashCode(): Int {
        return id.hashCode()
    }
}

RChild:

open class RChild constructor(
    @PrimaryKey
    @Required
    var id: String = UUID.randomUUID().toString(),
    var name: String = ""
) : RealmObject() {

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as RChild

        if (id != other.id) return false

        return true
    }

    override fun hashCode(): Int {
        return id.hashCode()
    }
}

Currently to remove RParent by id I use this func, also nested objects needs to be removed:

val realm = Realm.getDefaultInstance()
val event = realm.where(RParent::class.java)
                 .equalTo("id", "parent1")
                 .findFirst()
event?.childs?.deleteAllFromRealm() // Removing all childs of the parent. I think the method needs to be improved.
event?.deleteFromRealm()
realm.close()

I want to write common func for all my databases like this, but method deleteAllFromRealm doesn't remove nested list:

  suspend inline fun <reified T : RealmObject> inlineRemoveItemBySuspend(
        fieldName: String,
        fieldValue: String
    ): Boolean {
        return withContext(AppDispatchers.IO) {
            val realm = getRealm()
            try {
                realm.executeTransaction { realm ->
                    realm
                        .where(T::class.java)
                        .equalTo(fieldName, fieldValue)
                        .findAll()
                        ?.deleteAllFromRealm()
                }
            } finally {
                if (!realm.isClosed) {
                    realm.close()
                }
            }
            true
        }
    }

    fun getRealm() = Realm.getInstance(
        RealmConfiguration.Builder()
            .deleteRealmIfMigrationNeeded()
            .schemaVersion(dbVersionNumber.toLong())
            .encryptionKey(encryptionKey)
            .modules(baseModule, *additionalModules)
            .name("$name.realm").build()
    )

The same for func io.realm.Realm#insertOrUpdate(io.realm.RealmModel)

Solution

No response

Alternatives

No response

How important is this improvement for you?

Would be a major improvement

Feature would mainly be used with

Local Database only

cmelchior commented 1 year ago

Hi @Kolyall Thank you for this request. I'll fold this into https://github.com/realm/realm-java/issues/1104 as a duplicate.

Note that we have support for Embedded Objects, which do support cascading deletes, but have other tradeoffs like not allowing primary keys https://www.mongodb.com/docs/realm/sdk/java/data-types/embedded-objects/