cancel
Showing results for 
Search instead for 
Did you mean: 

Unsupported operation when handling refresh of objects in Backoffice

Former Member
0 Kudos

Hello,

I have been digging in to our logs and found one error in Backoffice that keeps happening. We are running Hybris 6.7

When some CRUD operation is performed in Backoffice the backing objectFacade send out events to notify other widgets that an object changed so that they can update their models if needed. One such event goes through: com.hybris.cockpitng.widgets.collectionbrowser.mold.impl.DefaultSelectAndFocusDelegateController#handleSelectionRefresh

This looks like this:

 protected void handleSelectionRefresh(Collection<?> updatedObjects) {
         List<Object> oldObjects = new LinkedList();
         Collection<Object> selectedItems = this.getController().getSelectedItems();
         updatedObjects.forEach((updatedObject) -> {
             selectedItems.stream().filter((oldObject) -> {
                 return oldObject.equals(updatedObject);
             }).forEach(oldObjects::add);
         });
         if (!oldObjects.isEmpty()) {
             selectedItems.removeAll(oldObjects);
             selectedItems.addAll(updatedObjects);
             this.getController().getModel().changed("selectedObjects");
         }
 
         this.getController().handleSelectionRefresh(updatedObjects);
     }

Notice the if case when oldObjects isn't empty. Then it removes all objects in the selectedItems collection and adds the latest updated objects. Now lets see where these selectedItems come from:

 public <E> Collection<E> getSelectedItems() {
         WidgetModel widgetModel = this.getController().getWidgetInstanceManager().getModel();
         Optional<Collection> selected = Optional.ofNullable(widgetModel.getValue("selectedObjects", Collection.class));
         Collection<E> result = (Collection)selected.orElse(Collections.emptyList());
         if (!this.getController().isMultiSelectEnabled() && CollectionUtils.size(result) > 1) {
             result = Collections.singleton(SelectAndFocusDelegateController.getSelectedItem((Collection)result));
         }
 
         return (Collection)result;
     }

Now look at that if case there. Notice what it sets the result to an immutable singleton set in case it goes there. So when this happens and there are old objects it will try to do removeAll on that returned immutable singleton set which is an unsupported operation.

This must be a bug right? In any case if other people find this in their logs you can extend: com.hybris.cockpitng.widgets.collectionbrowser.mold.impl.DefaultSelectAndFocusDelegateController

 @Override
     public <E> Collection<E> getSelectedItems() {
         return new LinkedHashSet<>(super.getSelectedItems());
     }

Now it will not crash here and everything will work. So what is the result that it crashes here? Well, not super obvious because this affects the related widgets during the last step of refreshing their models so it won't be the first thing you notice but it really shouldn't crash here regardless.

Regards

Former Member
0 Kudos

If I am missing something feel free to share that. I'm not completely sure when this case occurs in order to reproduce it. All I know is that it does happen now and then and we see those errors in the logs. My solution above solves that but I'm not sure if it has other unintended side effects

Accepted Solutions (1)

Accepted Solutions (1)

former_member625836
Active Contributor
0 Kudos

Hi ,

A short glimpse on your analysis tells me that you are right. I have created an issue in our backlog to make sure that this one is fixed.

Thanks,

Answers (0)