enhancement
critical
major
minor
minor
critical
#26311
GridComponent: Programmatic invalidation after multi-selection leads to undefined behavior
When using the GridComponent to display persistent objects in a table and with multiselection enabled (via the checkbox column), a situation can arise in which the component’s internal GUI model becomes inconsistent, leading to undefined behavior. The scenario is as follows:
- Select multiple rows in the GridComponent using the checkbox column
- Programmatically invalidate the component (using GridComponent.invalidate())—for example, by clicking a button.
- Select an additional row
=> A ClassCastException is thrown, and the selection does not match the expected result; instead, sometimes completely different rows are selected, or suddenly nothing at all.
=== Analysis In `com.top_logic.element.layout.grid.AbstractGridHandler.selectionToFormGroups(Object)`, only sets are handled correctly. However, after programmatic invalidation, the selection appears to be in the form of a list. Among other things, this also causes the server-side GUI model (the FormGroups) to be incorrectly annotated, so that the same row is assigned multiple business objects under `GridComponent.PROP_ATTRIBUTED `.
If you then attempt to execute business logic based on the selection, the business logic is executed on completely incorrect objects.
Improvement
As part of #24566, several improvements were made to the grid selection, which resulted in selections suddenly being stored as lists rather than sets. Since the program is not designed for this, it leads to the behavior described. To save the selection as a set again, the return value of `com.top_logic.element.layout.grid.GridUtil.getBusinessObjectsFromInternalRows(Collection<?>) ` (and all methods called within it) was changed from ` List ` to `LinkedHashSet `.
Test
**On TL_6x:** Create a view with a grid that supports multi-selection. Alternatively, you can simply use this view: Technical Demo > Tests > External Selection > External Selection in Grid. Additionally, a button for invalidating the selection must be added. To customize the grid in the upper-left corner, the following must be added to the grid named "gridDemo1" in gridExternalSelection.xml: {{{#!xml <buttons>
<reference command-id="invalidate"/>
</buttons> }}} Now start the application and switch to the corresponding view. Select a few rows in the customized grid and then click the newly added "invalidate" button. The selection must be retained, and no error message should appear. Additional selections must also work without generating any error messages.
**On TL_7x** Since the corresponding functions are not used here, here is a refactoring.