Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overriding field name with @LinkingObjects results in Property could not be found #6581

Closed
dsuresh-ap opened this issue Aug 9, 2019 · 3 comments

Comments

@dsuresh-ap
Copy link

dsuresh-ap commented Aug 9, 2019

Goal

Create a schema with a many-to-many relationship. Every Release object has a list of Users that it belongs to. Every User has a list of Releases it belongs to.

Actual Results

2019-08-09 13:07:34.552 4848-4848/com.example.realmsampleapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.realmsampleapp, PID: 4848
    java.lang.IllegalStateException: Property 'favoriteProcesses' cannot be found.
    (/Users/Nabil/Dev/realm/master4/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsObjectSchemaInfo.cpp:119)
        at io.realm.internal.OsObjectSchemaInfo.nativeGetProperty(Native Method)
        at io.realm.internal.OsObjectSchemaInfo.getProperty(OsObjectSchemaInfo.java:174)
        at io.realm.internal.ColumnInfo.addBacklinkDetails(ColumnInfo.java:270)
        at io.realm.com_example_realmsampleapp_models_realmobjects_process_ReleaseRealmObjectRealmProxy$ReleaseRealmObjectColumnInfo.<init>(com_example_realmsampleapp_models_realmobjects_process_ReleaseRealmObjectRealmProxy.java:77)
        at io.realm.com_example_realmsampleapp_models_realmobjects_process_ReleaseRealmObjectRealmProxy.createColumnInfo(com_example_realmsampleapp_models_realmobjects_process_ReleaseRealmObjectRealmProxy.java:690)
        at io.realm.DefaultRealmModuleMediator.createColumnInfo(DefaultRealmModuleMediator.java:71)
        at io.realm.internal.ColumnIndices.getColumnInfo(ColumnIndices.java:84)
        at io.realm.RealmSchema.getColumnInfo(RealmSchema.java:236)
        at io.realm.DefaultRealmModuleMediator.copyOrUpdate(DefaultRealmModuleMediator.java:164)
        at io.realm.Realm.copyOrUpdate(Realm.java:1700)
        at io.realm.Realm.copyToRealmOrUpdate(Realm.java:1091)
        at io.realm.RealmModelListOperator.copyToRealmIfNeeded(RealmList.java:1528)
        at io.realm.RealmModelListOperator.appendValue(RealmList.java:1456)
        at io.realm.ManagedListOperator.append(RealmList.java:1337)
        at io.realm.RealmList.add(RealmList.java:210)
        at com.example.realmsampleapp.utils.FavProcessRealmOperations$addProcessToFavoriteList$1.execute(FavProcessRealmOperations.kt:58)
        at io.realm.Realm.executeTransaction(Realm.java:1493)
        at com.example.realmsampleapp.utils.FavProcessRealmOperations.addProcessToFavoriteList(FavProcessRealmOperations.kt:57)
        at com.example.realmsampleapp.ui.viewmodel.FavoriteProcessFragmentViewModel.onFavoriteProcessClicked(FavoriteProcessFragmentViewModel.kt:34)
        at com.example.realmsampleapp.ui.fragments.FavoriteProcessFragment.onProcessClicked(FavoriteProcessFragment.kt:94)
        at com.example.realmsampleapp.ui.adapter.ProcessViewHolder$bind$1.onCheckedChanged(ProcessViewHolder.kt:24)
        at android.widget.CompoundButton.setChecked(CompoundButton.java:182)
        at android.widget.CompoundButton.toggle(CompoundButton.java:136)
        at android.widget.CompoundButton.performClick(CompoundButton.java:141)
        at android.view.View.performClickInternal(View.java:7299)
        at android.view.View.access$3200(View.java:846)
        at android.view.View$PerformClick.run(View.java:27773)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:6986)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)

Steps & Code to Reproduce

Add Release to User's list of releases:

val userPrimaryKey = "key" // Actual key different

        val userRealmObject = realm.where(UserRealmObject::class.java).equalTo("id", userPrimaryKey).findFirst()
        val favoriteProcesses = userRealmObject?.favoriteProcesses
        val isCurrentProcessInFavoriteList = favoriteProcesses?.any { releaseRealmObject ->
            releaseRealmObject.id == processRealmObject.id
        }

        if (isCurrentProcessInFavoriteList == false) {
            realm.executeTransaction {
                favoriteProcesses.add(processRealmObject)
            }
        }
Models
@RealmClass(name = "UserRealmObject", fieldNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
open class UserRealmObject : RealmObject() {
  
    @RealmField("favorite_processes") // Linked object fields must match Kotlin names
    var favoriteProcesses: RealmList<ReleaseRealmObject> = RealmList()

    @PrimaryKey
    @RealmField("id")
    var id: String? = null
}

@RealmClass(name = "ReleaseRealmObject", fieldNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
open class ReleaseRealmObject : RealmObject() {

    @PrimaryKey
    @RealmField("id")
    var id: Int? = null

    @RealmField("users")
    @LinkingObjects("favoriteProcesses")
    val users: RealmResults<UserRealmObject>? = null
}

To fix prevent the crash, we had to remove fieldNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES and also
from @RealmField("favorite_processes") from UserRealmObject. Or we could keep fieldNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES and change @RealmField("favorite_processes") to @RealmField("favoriteProcesses").

It seems like when we override the field name and when Realm attempts to add a backlink, it expects the Kotlin field name in the schema rather than the overriden field name.

Version of Realm and tooling

Realm version(s): plugin 5.13.0

Realm Sync feature enabled: No

Android Studio version: 3.4.2

Android Build Tools version: 29.0.0

Gradle version: 3.4.2

Which Android version and device(s): Samsung S9 9.0

@cmelchior
Copy link
Contributor

This looks like a bug. The @LinkingObjects input should be the names defined in Java, e.g. @LinkingObjects("favoriteProcesses") should work regardless of how and what the underlying Realm field gets mapped to.

I'll take a look.

@bmunkholm
Copy link
Contributor

@cmelchior Can this be closed now with the above fix?

@RealmBot
Copy link
Collaborator

➤ Christan Melchior commented:

Fixed by #6582 ( #6582 )

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants