realm / realm-kotlin

Kotlin Multiplatform and Android SDK for the Realm Mobile Database: Build Better Apps Faster.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RealmSet<class String> is detected as RealmSet<class UnmanagedRealmSet> for DynamicMutableRealmObject.set when doing migration

p0058781 opened this issue · comments

How frequently does the bug occur?

Always

Description

Old schema:

class RealmGame : RealmObject {
    ...
    var executablePath: String? = null
    ...
}

New schema:

class RealmGame : RealmObject {
    ...
    var executablePaths: RealmSet<String> = realmSetOf()
    ...
}

Migration:

private class MyMigration : AutomaticSchemaMigration {
    override fun migrate(migrationContext: AutomaticSchemaMigration.MigrationContext) {
        migrationContext.enumerate(RealmGame::class.simpleName!!) { oldObject: DynamicRealmObject, newObject: DynamicMutableRealmObject? ->
            newObject?.run {
                val executablePath: String? = oldObject.getNullableValue("executablePath")
                executablePath?.let {
                    set<RealmSet<String>>(
                        "executablePaths",
                        realmSetOf<String>(it)
                    )
                }
            }
        }
    }

}

Stacktrace & log output

Caused by: java.lang.IllegalArgumentException: Trying to access property 'RealmGame.executablePaths' as type: 'RealmSet<class io.realm.kotlin.internal.UnmanagedRealmSet>' but actual schema type is 'RealmSet<class kotlin.String>'
	at io.realm.kotlin.internal.RealmObjectHelper.checkPropertyType(RealmObjectHelper.kt:1230)
	at io.realm.kotlin.internal.RealmObjectHelper.dynamicGetSet$io_realm_kotlin_library(RealmObjectHelper.kt:965)
	at io.realm.kotlin.internal.RealmObjectHelper.dynamicGetSet$io_realm_kotlin_library$default(RealmObjectHelper.kt:957)
	at io.realm.kotlin.internal.RealmObjectHelper.dynamicSetValue$io_realm_kotlin_library(RealmObjectHelper.kt:1132)
	at io.realm.kotlin.internal.RealmObjectHelper.dynamicSetValue$io_realm_kotlin_library$default(RealmObjectHelper.kt:1028)
	at io.realm.kotlin.internal.dynamic.DynamicMutableRealmObjectImpl.set(DynamicMutableRealmObjectImpl.kt:134)
	at org.skynetsoftware.avnlauncher.data.database.MyMigration$migrate$1.invoke(DatabaseKoinModule.kt:32)
	at org.skynetsoftware.avnlauncher.data.database.MyMigration$migrate$1.invoke(DatabaseKoinModule.kt:28)
	at io.realm.kotlin.migration.AutomaticSchemaMigration$MigrationContext$DefaultImpls.enumerate(AutomaticSchemaMigration.kt:112)
	at io.realm.kotlin.internal.ConfigurationImpl$migrationCallback$1$1$1.enumerate(ConfigurationImpl.kt:172)
	at org.skynetsoftware.avnlauncher.data.database.MyMigration.migrate(DatabaseKoinModule.kt:28)
	at io.realm.kotlin.internal.ConfigurationImpl.lambda$3$lambda$2(ConfigurationImpl.kt:172)
	at io.realm.kotlin.internal.interop.realmcJNI.realm_open(Native Method)
	at io.realm.kotlin.internal.interop.realmc.realm_open(realmc.java:426)
	at io.realm.kotlin.internal.interop.RealmInterop.realm_open(RealmInterop.kt:235)
	at io.realm.kotlin.internal.ConfigurationImpl$openRealm$2.invoke(ConfigurationImpl.kt:115)
	at io.realm.kotlin.internal.ConfigurationImpl$openRealm$2.invoke(ConfigurationImpl.kt:114)
	at io.realm.kotlin.internal.interop.NativePointerKt.use(NativePointer.kt:53)
	at io.realm.kotlin.internal.ConfigurationImpl.openRealm$suspendImpl(ConfigurationImpl.kt:114)
	at io.realm.kotlin.internal.ConfigurationImpl.openRealm(ConfigurationImpl.kt)
	at io.realm.kotlin.internal.RealmImpl$1.invokeSuspend(RealmImpl.kt:130)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:280)
	at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
	at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
	at io.realm.kotlin.internal.platform.CoroutineUtilsSharedJvmKt.runBlocking(CoroutineUtilsSharedJvm.kt:22)
	at io.realm.kotlin.internal.platform.CoroutineUtilsSharedJvmKt.runBlocking$default(CoroutineUtilsSharedJvm.kt:21)
	at io.realm.kotlin.internal.RealmImpl.<init>(RealmImpl.kt:112)
	at io.realm.kotlin.internal.RealmImpl.<init>(RealmImpl.kt)
	at io.realm.kotlin.internal.RealmImpl$Companion.create$io_realm_kotlin_library(RealmImpl.kt:308)
	at io.realm.kotlin.Realm$Companion.open(Realm.kt:83)
	at org.skynetsoftware.avnlauncher.data.database.DatabaseKoinModuleKt$databaseKoinModule$1$1.invoke(DatabaseKoinModule.kt:22)
	at org.skynetsoftware.avnlauncher.data.database.DatabaseKoinModuleKt$databaseKoinModule$1$1.invoke(DatabaseKoinModule.kt:17)
	at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
	... 37 more

Can you reproduce the bug?

Always

Reproduction Steps

No response

Version

1.13.0

What Atlas App Services are you using?

Local Database only

Are you using encryption?

No

Platform OS and version(s)

Kotlin Multiplatform JVM

Build environment

Intellij IDEA version: 2023.3.2
Android Build Tools version: 8.0.2
Gradle version: 8.2.1

You shouldn't use set on the RealmSet-property. Instead you need to obtain a reference to the RealmSet of your newObject and add the elements to it with something like

getValueSet<String>("executablePaths").add(it)

Ah, ok, works like that. Thank you
I was following Change an Object Model - Kotlin SDK
That guide could probably also be updated to mention that