View entity objects accumulate in client state: every refresh adds a full duplicate set
0
## Questions1. Is this the expected behaviour of view entities in the client state?2. Is there a supported way to release view entity objects that are no longer displayed, short of a full page reload?3. Are there plans to give view entity rows a stable identity across retrieves, so the client can deduplicate them?## Environment- Mendix 11.12.4- SQL Server- Web client, Chromium- View entities (OQL v2)## SummaryObjects retrieved through a **view entity** appear to receive a new GUID on everyretrieve. Because non-persistable objects are only removed from the client state whenthey are no longer "used", the previous set is never released. The result is that**every refresh of a list view backed by a view entity adds a complete duplicate set ofobjects to the client state**, which then travels with every subsequent request.We are aware of[Non-Persistable Objects and Garbage Collecting](https://docs.mendix.com/refguide/transient-objects-garbage-collecting/)and believe this is a specific consequence of that design when combined with viewentities, rather than a modelling mistake on our side. We would like to know whetherthis is expected behaviour.## What we observeA page shows a timetable grid. Cells come from a view entity (`Cel`), column headersfrom a second view entity (`Header`).With 350 cells on screen:| | Before | After editing one single cell || --- | --- | --- || `Cel` objects in client state | 350 | **700** || Unique cells (by natural key) | 350 | 350 || Distribution | every key once | **every key exactly twice** || Cells rendered in the DOM | 350 | 350 || Client state size | 0.34 MB | 0.63 MB |Editing **one** cell duplicates the **entire** set, not just the edited row. The growthis linear in the number of refreshes, so a normal editing session quickly reaches tensof thousands of objects. In our case a user reached 19,082 objects and roughly 16 MB ofstate, at which point the runtime logged:```Request state size of 20425 objects exceeds the threshold of 100 objects. * MyModule.Cel (NPE): 19082 objects * MyModule.Header(NPE): 1316 objects```Interactions such as opening a pop-up became noticeably slow, which matches the statebeing serialised and sent with each request.## Nothing releases the objectsTested, each time followed by an explicit `collectGarbage()`:| Action | Objects released || --- | --- || Navigating to a different context (0 cells rendered) | none || Collapsing the accordions containing the list views | none || Switching to another tab | none || Navigating to a different page | none || Calling the client garbage collector explicitly | none || **Full page reload** | **all** |Persistable entities retrieved on the same page *were* released. Only thenon-persistable view entity objects remained. That is consistent with the documentation— persistable objects can be reloaded from the database, non-persistable ones cannot —but it means view entity results can only ever grow during a session.## Why we believe this is platform-levelView entity rows have no stable identity across retrieves. Two retrieves of the samelogical row produce two objects with different GUIDs, so the client has no way torecognise them as the same row and deduplicate. Combined with the rule thatnon-persistable objects are retained while "used", duplication on every refresh appearsunavoidable from the app side.## Reproduction1. Create a view entity over any table with, say, a few hundred rows.2. Show it in a list view.3. Trigger any action that commits a change to the underlying data and refreshes the list view.4. Inspect the client state (Ctrl + Alt + G, or count via the object cache).Expected: roughly one object per rendered row.Actual: one additional full set per refresh.## Our workaroundA JavaScript action that removes stale duplicates from the client object cache, keepingonly the most recently retrieved object per natural key, called after every action thatrefreshes the grid. This brings the state back to one object per rendered row and hasno visible side effects.It does rely on an internal, undocumented client API, which we would rather not dependon. Hence this question.Disclaimer: Written by A.I.