jmix icon indicating copy to clipboard operation
jmix copied to clipboard

Entity changes are not preserved in the UI when there is a deep composition relationships

Open OLODiman11 opened this issue 3 months ago • 1 comments

Environment

Jmix version: 2.7.0

Bug Description

Entity changes are not preserved in the UI when there is a deep composition relationships

Steps To Reproduce

  1. Run sample project
  2. Navigate to As
  3. Create entity A with name A1
  4. Create entity B with name B1
  5. Create entity C with name C1
  6. Create entity D with name D1
  7. Save everything Now you should have the following relationships: A1 > B1 > C1 > D1
  8. Open edit view for A1
  9. Open edit view for B1
  10. Open edit view for C1
  11. Open edit view for D1
  12. Change its name to D2
  13. Save all but A1, keep it open
  14. Open edit view for B1 again
  15. Open edit view for C1 again
  16. The name of the D entity remains D1 in the UI

Current Behavior

The name of the D entity remains D1 in the UI

Expected Behavior

The name of the D changes to D2 in the UI

Notes

After step 13, only C1 and D1 are marked as modified in the a-detail-view context, but not B1. So when opening the B1 view again it provides the original B1 which does not have any changes in C1 and D1 .

Sample Project

nested-composition-bug.zip

OLODiman11 avatar Nov 24 '25 14:11 OLODiman11

There is a workaround: in each intermediate detail view (except the root and the last ones), add the listener for the next level entity changes to mark the current entity instance modified.

This is shown in UI Samples: https://demo.jmix.io/ui-samples/sample/composition-2-levels?tab=TerminalDetailView.java

For the attached project, this means adding the following handlers:

public class BDetailView extends StandardDetailView<B> {

    @ViewComponent
    private DataContext dataContext;

    @Subscribe(id = "csDc", target = Target.DATA_CONTAINER)
    public void onCsDcItemPropertyChange(final InstanceContainer.ItemPropertyChangeEvent<C> event) {
        B b = getEditedEntity();
        dataContext.setModified(b, true);
    }
}
public class CDetailView extends StandardDetailView<C> {

    @ViewComponent
    private DataContext dataContext;

    @Subscribe(id = "dsDc", target = Target.DATA_CONTAINER)
    public void onDsDcItemPropertyChange(final InstanceContainer.ItemPropertyChangeEvent<D> event) {
        C c = getEditedEntity();
        dataContext.setModified(c, true);
    }
}

knstvk avatar Dec 09 '25 13:12 knstvk