Как вставить связанную коллекцию программно?

Зравствуйте.
Jmix version: 2.1.2
Jmix Studio plugin version: 2.1.2-232
IntelliJ version: IntelliJ IDEA 2023.2.5 (Community Edition)

Есть сущность “Отдел”, в ней есть связанное свойство “Сотрудники”.
При показе экрана сущности “Отдел” - на экране поля свойств Отдела и сотрудники в виде DataGrid. У DataGrid удалены кнопки, добавить удалить и т.д. То есть пользователь не может вручную добавлять сотрудников.
Есть специальная кнопка “Добавить сотрудников”, при нажатии на которую List должен
поместиться в сущность “Отдел”. Как правильно это сделать?

  1. Делал через сеттер Department.setUsers(List) и через CollectionContainer.setItems(). При этом DataGrid на экране заполняется. Но при сохранении сущности Отдел, сохранения списка сотрудников в данном отделе не происходит.
    Как я понимаю CollectionContainer как связанное свойство входит в DataContext, почему тогда не сохраняется? Или надо вручную в каждую сущность как то прописывать ForeingKey?
    Как правильно сохранить в БД? Только через DataManager?

Вопрос почему вы не используете стандартное action Добавления…

Если я правильно понимаю, у вас у Юзера есть ссылка на Отдел.

Вам нужно добавить список юзеров в контекст экрана - dataContext.merge(user);, так экран начнет отслеживать их состояние, и если сущность обновиться, то и сохраниться.

И так же у юзеров проставить ссылки на отдел. В данный момент контекст экрана пометит сущности как обновленные и при сохранении экрана, обновит и юзеров.

  1. Список сотрудников должен быть импортирован из другого источника. То есть я имею подготовленный List.

  2. Правильно я понимаю что если collection входит как property в instance(в xml файле экрана) то оно автоматически входит в dataContext? По крайней мере я вижу прикрепленных пользователей вызвав
    Set removed =dataContext.getRemoved();
    Set modyfied =dataContext.getModified();?

  3. Делаю так
    departmentDc.getMutableItems().clear; //очищаю от предыдущих сотрудников
    userList.forEach( user → {
    user.setDepartment(department);//присваиваю явно данный отдел каждому пользователю(хотя может это и не надо делать, может автоматически присвоиться далее)
    });
    departmentDc.setItems(userList);//вот здесь наверное должно автоматически присвоиться каждому пользователю данный отдел
    Set modyfied =dataContext.getModified(); //вижу здесь добавленных пользователей в отдел

При этом вижу что на экране в таблице изменились сотрудники

Но затем при нажатии кнопки “Ок” и закрытии экрана редактирования Отдела, сохраняются только поля измененные поля отдела, а сотрудники нет((.
Чтот-то я упускаю(

Если вы не хотите чтоб старые юзера были привязаны к отделу, то у них нужно убрать ссылку на отдел.

Странно… А можете предоставить демо проект? Тяжело сейчас сказать что не так.

Да, постараюсь сделать демо проект, может не сегодня, а в понедельник, как успею. Заранее спасибо.

DepartmentUser.zip (4.0 МБ)

Тестовый проект “Отделы и пользователи”.

  1. При корректировке Department можно нажать кнопку Import User и должны импортироваться пользователи.
  2. На экране dataGrid обновляется, но при сохранении Department пользователи не сохраняются (только основные поля Department, например Building).
  3. При этом я сделал стандартную кнопку Add для добавления пользователя-она работает и Department сохраняет.

Да.

Нет, не должно.

Запустил ваш код, и я не вижу такого.

Не вижу данного действия в вашем коде.

Так все работает:

        List<User> usersForImport = dataManager.load(User.class).
                query("select e from User e").list();
        EntitySet merged = dataContext.merge(usersForImport);
        merged.forEach(obj -> {
            if (obj instanceof User user) {
                user.setDepartment(getEditedEntity());
                userDc.getMutableItems().add(user);
            }
        });
1 симпатия

Спасибо, большое-заработало.
Я думал что:

  1. Если userDc уже входит в dataContext, то пользователей не надо добавлять в merge и все что я изменяю в userDc, автоматически сохраняется.
  2. Если даже добавил список в dataContext то могу работать с ним (а не с возвращаемым EntitySet), в нем уже все отслеживается.
  3. По поводу
    Set modyfied =dataContext.getModified()
    я там видел сущность Department и в нем список сущностей User, именно столько сколько и добавил.
    Спасибо за помощь.