You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Update the feed name in the app or on the server side.
Open the feed and look at its items. Each item has the name of the feed it belongs to.
After the first feed name changing, most likely you will see that it has also changed in the items. But if you change the name again without close the app, then this will no longer affect the name in the items, it will remain the same.
Record_09032022_122302.mp4
I tried to research this issue. Next, I will give pieces of the problematic code.
So, the RssItem entity is responsible for information about visible items. This class contains a "to-one" relationship with the Feed entity.
When the UI code wants to get information about a feed that belongs to an item (for example, to display the name of the feed for that item), it calls this method:
/** To-one relationship, resolved on first access. */
publicFeedgetFeed() {
long__key = this.feedId;
if (feed__resolvedKey == null || !feed__resolvedKey.equals(__key)) {
if (daoSession == null) {
thrownewDaoException("Entity is detached from DAO context");
}
FeedDaotargetDao = daoSession.getFeedDao();
FeedfeedNew = targetDao.load(__key);
synchronized (this) {
feed = feedNew;
feed__resolvedKey = __key;
}
}
returnfeed;
}
It just fetch the Feed entity from the DB and caches it. When we call this method again, it will fetch the Feed entity from its cache (and also saves the feed id to the feed__resolvedKey variable). Therein lies the problem.
When we open the list of items of the selected feed, or there is a synchronization, this DB ORM method is called:
It creates a raw DB query to get the RssItem entities for the selected feed (or any other fragment page like non-read or favourite items). I'm new to greenDAO but I tried to learn its behavior. Apparently, on the first query to get RssItem, it caches the entities. When a sync occurs, or we open the fragment with the items list, we get cached RssItem entities. To be more precise, we get entities with a cached Feed entity inside each. By calling the RssItem#getFeed() method, we get the old cached data, including the old feed name.
Also, RssItem has a setFeed() method which is used in RssItemDao to retrieve a deep copy of RssItem:
So I verified that if I call RssItemDao#queryDeep() instead of RssItemDao#queryRaw() in the ORM, then I get the actual feed name, not the old data, because now the DAO is freshly sets Feed entities within RssItem entities.
It turns out that the problem is either in the caching of entities by the DAO itself, or the problem is in caching the "to-one" relationship with the Feed entity inside the RssItem entity. One way or another, this creates a problem when we don't get up-to-date data, for example, about the feed name.
Possible solutions:
I don't know how to do it right, but I see two ways out of this situation and would like to discuss it:
Always use the RssItemDao#queryDeep() method, although this is likely to create overhead if you have many items.
Consider a cache invalidation mechanism after synchronization. Perhaps greenDAO has the necessary settings and methods for this, or we need to implement it manually.
So far, I haven't submitted any fixes to the RP, as I don't know the possible subtleties and problems that these changes will lead to, discussion with the maintainers (@David-Development) is necessary.
The text was updated successfully, but these errors were encountered:
@proninyaroslav Thank you for the thorough ticket. I wasn't really aware of that caching behavior.
I just went through the docs and saw that they have an option to clear the session's cache daoSession.clear();
Wondering if you could call that in the OwnCloudSyncAdapter once the sync is finished..? Not sure if it has other side-effects with the existing data visible in the app. Otherwise I agree, queryDeep seems like a good alternative. Not sure what the performance implications are but we are not constantly querying so it shouldn't be a huge issue.
Ok, I'll try both options, although deepQuery is probably a cleaner way, there are no hidden or additional conditions like cleaning DAO, which you may not know or forget about when writing new code or maintaining old.
Problem:
Record_09032022_122302.mp4
I tried to research this issue. Next, I will give pieces of the problematic code.
So, the
RssItem
entity is responsible for information about visible items. This class contains a "to-one" relationship with theFeed
entity.When the UI code wants to get information about a feed that belongs to an item (for example, to display the name of the feed for that item), it calls this method:
news-android/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/RssItem.java
Lines 257 to 272 in 9bb275d
It just fetch the
Feed
entity from the DB and caches it. When we call this method again, it will fetch theFeed
entity from its cache (and also saves the feed id to thefeed__resolvedKey
variable). Therein lies the problem.When we open the list of items of the selected feed, or there is a synchronization, this DB ORM method is called:
news-android/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnectionOrm.java
Lines 467 to 475 in f8c0115
It creates a raw DB query to get the
RssItem
entities for the selected feed (or any other fragment page like non-read or favourite items). I'm new to greenDAO but I tried to learn its behavior. Apparently, on the first query to getRssItem
, it caches the entities. When a sync occurs, or we open the fragment with the items list, we get cachedRssItem
entities. To be more precise, we get entities with a cachedFeed
entity inside each. By calling theRssItem#getFeed()
method, we get the old cached data, including the old feed name.Also,
RssItem
has asetFeed()
method which is used inRssItemDao
to retrieve a deep copy ofRssItem
:news-android/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/RssItem.java
Line 274 in 4444d6f
news-android/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/RssItemDao.java
Lines 381 to 385 in 03a88f7
news-android/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/RssItemDao.java
Lines 241 to 251 in 03a88f7
So I verified that if I call
RssItemDao#queryDeep()
instead ofRssItemDao#queryRaw()
in the ORM, then I get the actual feed name, not the old data, because now the DAO is freshly setsFeed
entities withinRssItem
entities.It turns out that the problem is either in the caching of entities by the DAO itself, or the problem is in caching the "to-one" relationship with the
Feed
entity inside theRssItem
entity. One way or another, this creates a problem when we don't get up-to-date data, for example, about the feed name.Possible solutions:
I don't know how to do it right, but I see two ways out of this situation and would like to discuss it:
RssItemDao#queryDeep()
method, although this is likely to create overhead if you have many items.So far, I haven't submitted any fixes to the RP, as I don't know the possible subtleties and problems that these changes will lead to, discussion with the maintainers (@David-Development) is necessary.
The text was updated successfully, but these errors were encountered: