Infinite Loop due to dataContext.isModified

Jmix version: 2.5.2
Jmix Studio Plugin Version: 2.7.1-253
IntelliJ version: IntelliJ IDEA 2025.3.1

We have a view with a fragment. In the fragment we are editing a DTO. If the DTO is saved we fire an event. This event is subscribed by the view and the fragment because there could be multiple instances that shall not display obsolete data.
If a new entity is set to the fragment it checks with dataContext.isModified(oldEntity) and saves the old entity if there are unsaved changes.

Sometimes this causes an endless saving loop.

  1. Fragment saves and fires the event
  2. View gets the event and changes the entity in the fragment to the updated entity from the event. The old entity is eviced from dataContext and freshly merged.
  3. Fragment gets the event and changes the entity again. Due to some magic dataContext.isModified(oldEntity) evaluates to true and the fragment saves the old entity again and starts an endless loop.

I don’t understand why dataContext says that the entity is modified in this case.

Do you have any idea how to debug this? How would you avoid the possibility of an endless loop in this case?

I have further debugged and found one reason. I’m not sure if it’s the only reason, so I would like any further hints.

  1. create an (JPA) entity with an association e.g. to User
  2. create a view with a entity combo box like <entityComboBox id="userPicker" property="user" itemsContainer="usersDc"/>
  3. create an items fetch callback like
@Install(to = "userPicker", subject = "itemsFetchCallback")
    private Stream<User> userPickerItemsFetchCallback(final Query<User, String> aQuery)
    {
        final String rawQueryStr = aQuery.getFilter().orElse(null);

        // TODO load according max results and offset.
        return dataManager.load(User.class)
                        .query("e.username = :searchString")
                        .parameter("searchString", rawQueryStr)
                        .list()
                        .stream();
    }
  1. create a method where you can load the item manually to the data container.

In this case the User instance is different from the instance in the entity in the dataContext. This triggers an EntityPropertyChangeEvent and marks this entity as modified in the moment when it’s loaded. Perhaps it would be good to check for the content before the flag is set?

As workaround I set the modified flag back to false manually directly after setting the entity to the data container. What do you think?