ItemPropertyChangeEvent не работает для DTO сущностей

Добрый день!
Jmix version: 1.5.3
Jmix Studio plugin version: 2.0.3-232
IntelliJ version: IntelliJ IDEA 2023.2.1 (Community Edition)

В экране имеем коллекцию данных с DTO сущностью, которая заполняется через loadDelegate.
Для изменения используется компонент - treeTable.
При изменении объекта коллекции не срабатывает обработчик события ItemPropertyChangeEvent

    @Subscribe(id = "locationGrantAccessesDc", target = Target.DATA_CONTAINER)
    protected void onLocationGrantAccessesDcItemPropertyChange(final InstanceContainer.ItemPropertyChangeEvent<LocationGrantAccess> event) {
        if (List.of("read", "edit").contains(event.getProperty())) {
            log.debug("Changed: {}", event.getProperty());
        }
    }

События CollectionChangeEvent и ItemChangeEvent срабатывают.

В чем может быть дело?

Создал пример проекта
changes.zip (92.6 КБ)
С разным вариантом загрузки
image
При нажатии на чекбоксы должно появиться нотификация из обработчика события ItemPropertyChangeEvent
image

Делал по аналогии с EntityAttributeResourcePolicyModelCreate. Тут работает, у меня - нет.

Нашел проблему.
Jmix НЕ вешает слушателя на изменения атрибутов, у которых сеттер возвращает значение.

    public NewEntity setCheckValue(Boolean checkValue) {
        this.checkValue = checkValue;
        return this;
    }

Может это и фича, но думаю - баг, который надо бы исправить.

Такие сеттеры генерит Idea
image

Как только поменял результат сеттера на void, все заработало.

Олег, здравствуйте!

Да, многие библиотеки поддерживают fluent- сеттеры, поэтому в Idea есть такой шаблон (Builder) и, видимо, он у вас был выбран при последней генерации:
Снимок экрана 2023-10-04 в 15.25.19

Однако, такой тип сеттеров противоречит спецификации JPA (см. § 2.2):

It is required that the entity class follow the method signature conventions for JavaBeans read/write
properties (as defined by the JavaBeans Introspector class) for persistent properties when property
access is used.

In this case, for every persistent property property of type T of the entity, there is a getter method, getProperty, and setter method setProperty. For boolean properties, isProperty may be used as an alternative name for the getter method.[2]

For single-valued persistent properties, these method signatures are:

  • T getProperty()
  • void setProperty(T t)

Поэтому для атрибутов сущностей нужно использовать только классические сеттеры, возвращающие void.

C уважением,
Дмитрий

1 симпатия