I have three classes with the following relationships:
class Feed : RealmObject {
var items: RealmList<FeedItem> = realmListOf()
}
class FeedItem : RealmObject {
val feed: RealmResults<Feed> by backlinks(Feed::items)
}
class FeedMedia: EmbeddedRealmObject {
var item: FeedItem?
}
I persisted them with this:
realm.write {
for (item in feed.items) {
item.feedId = feed.id
val media = item.media
if (media != null) {
media?.item = item
}
}
copyToRealm(feed)
}
Then given a feedMedia object, I want to get the feed,
val item = media.item
val feed = item.feed.first()
The first line above works, but the second to get the feed throws an NoSuchElementException:
failed because it threw an exception/error
java.util.concurrent.ExecutionException: java.util.NoSuchElementException: List is empty.
at androidx.work.impl.utils.futures.AbstractFuture.getDoneValue(AbstractFuture.java:515)
at androidx.work.impl.utils.futures.AbstractFuture.get(AbstractFuture.java:474)
at androidx.work.impl.WorkerWrapper$2.run(WorkerWrapper.java:316)
at androidx.work.impl.utils.SerialExecutorImpl$Task.run(SerialExecutorImpl.java:96)
At first glance it doesn’t appear the FeedMedia, which is an embedded object, was actually added to any parent object. In other words, EmbeddedObjects cannot exist alone - they actually become part of (e.g. embedded) the parent object they below to
So you would need to add a property to either Feed or FeedItem that will ‘hold’ the FeedMedia objects - it could be a realmListOf or a single property.
The block of code doesn’t say much without more context - the models are not showing what their properties are but more importantly…
…the code appears to modify a number of feed.items, assigning each feedId property the value of a feed.id but after that’s completed, the feed is written to realm, even though it was not modified. Is that the intention?
I also don’t see where any FeedItem Objects are added to Feed, hence the error showing there are none.
FeedItems are added to items in Feed elsewhere (outside of realm.write when everything was first created). After copying to realm, if I query the feeditems, I could actually get feed from every of the items. The problem seems to only happen when I try to get feed from media.item.
I tried to change FeedItem class to:
class FeedItem : RealmObject {
var feed: Feed? = null
}
abandoning the backlinks, assigned item.feed = feed in the for loop within realm.write block, everything works. It appears the auto-generation of backlinks is not reliably useful, or there are issues on how it should be used?
As you can see though, with just tidbits of code, we don’t understand the implementation.
In the question and then in the above comment, there’s a relationship between Feed and FeedItem - however, FeedMedia is nowhere to be found - it’s not added to Feed or FeedItem and FeedMedia is not an existing property of either (per the code).
See here
val media = item.media
in the code, item is a FeedItem but it does not have a media property so it will throw an error when attempting to access it.
The bottom line is, at least in the presented code, the backlink from FeedItem to Feed works perfectly but that’s totally unrelated to FeedMedia because there is no relationship there and it’s not populated with anything.
I suspect there more code so it may be a good idea to provide a bit more complete code, keeping it short) so we can see what’s actually going on.
That helps but the main problem persists; FeedItem.media is never populated so this will always results in that property being null
val media = item.media //item is a FeedItem and the .media property is not populated
if (media != null) {
We really need a more clear and duplicatable example of the issue and a better description of the problem. As-is, we are just guessing due to missing code.
It may be better to close this thread and craft a new question with example code we can run to duplicate the issue.
Thank you for the analysis. Does the stacktrace of the exception tell anything? I don’t know how to provide more info as with a rough start I abandoned using backlinks and turned to regular two-way relations for Feed and FeedItem and things work basically. I think the fundamental issue I have with the backlinks is that it’s by design not to be managed by the developer (which is OK) but at the same time isn’t always there (which is a problem).
Backlinks are highly flexible and a quite automated way to manage inverse relationships so the developer doesn’t have to manage them manually. They are easy to work with and maintain as well.
You can, as with almost any database, create your own forward and inverse relationship strategy but that’s a lot of extra work to bypass a provided feature - I recommend using the built-in functionality.
The problem is we don’t have a clear understanding of the implementation and it’s possible there’s just a simple coding issue that could be corrected.
We need to see a minimal, reproducible example of the issue. As is, the code is an incomplete implementation - as mentioned above the error NoSuchElementException sounds like it’s just a coding issue so a stack trace won’t really help. However, no way to know without example code that duplicates the problem.