Что нового

В данном разделе приведена информация о новой функциональности и возможных несовместимых изменениях в фреймворке Jmix и Jmix Studio версии 2.8. Примите их во внимание при обновлении с предыдущей версии фреймворка.

Для создания новых проектов в Jmix 2.8 или для апгрейда существующего проекта требуется Studio 2.8 или более поздней версии, поэтому в первую очередь обновите плагин Jmix Studio.

Минимальная требуемая версия IntelliJ IDEA / OpenIDE - 2025.2.

Раздел Апгрейд проекта содержит информацию о том, как обновить проект с помощью Studio. Процедура автоматической миграции вносит следующие изменения в ваш проект:

  • Обновляет версию Jmix BOM, которая, в свою очередь, определяет версии всех зависимостей.

  • Обновляет версию Jmix Gradle plugin.

См. полный список критических изменений, которые могут затронуть ваш проект после обновления.

Новая и улучшенная функциональность

Поддержка коллекций элементов

Модель данных Jmix теперь поддерживает коллекции базовых типов, объектов FileRef или кастомных типов. В JPA-сущностях эти атрибуты-коллекции аннотируются с помощью @ElementCollection и хранятся в отдельных таблицах базы данных.

См. раздел Сущности о том, как определять коллекции элементов, и Работа с DataManager о том, как использовать их в запросах.

Атрибуты-коллекции элементов по умолчанию загружаются лениво и могут быть включены в фетч-планы при необходимости.

Атрибуты-коллекции элементов могут использоваться в условиях компонента genericFilter и могут быть привязаны как значения компонентов multiValuePicker, multiSelectComboBox и multiSelectComboBoxPicker.

Чтобы создать атрибут-коллекцию элементов в Studio, выберите ELEMENT_COLLECTION в раскрывающемся списке Attribute type диалога New Attribute.

См. также #1271.

Визуализация модели данных в Data Tools

Дополнение Data Tools теперь включает экран Data Model для просмотра сущностей и их атрибутов в запущенном приложении. Экран также позволяет создать диаграмму модели данных (для всех сущностей или лишь для выбранного набора), используя публичный или собственный сервер PlantUML.

Динамические атрибуты в формах процесса

В дополнении BPM, процессные формы на базе экранов Jmix поддерживают загрузку и отображение динамических атрибутов. Для этого используйте аннотацию @ProcessVariableParam. Подробнее см. в разделе Загрузка динамических атрибутов.

Фасеты во фрагментах

Фрагменты теперь поддерживают фасеты. См. раздел Фасеты во фрагментах об их использовании, и информацию о связанных критических изменениях ниже:

Поддержка пользовательских иконок в компонентах

Многие компоненты теперь позволяют добавлять пользовательские иконки через вложенные элементы. Эти элементы обозначают конкретные слоты для иконок в компоненте — например, <icon>, <uploadIcon>, <dropdownIcon>. Пользовательские иконки могут быть добавлены в виде SVG файлов, иконочных шрифтов или изображений.

Например:

<button text="Download">
    <icon>
        <fontIcon fontFamily="lumo-icons" charCode="ea17"/>
    </icon>
</button>

Список компонентов: action, button, dropdownButton, comboButton, drawerToggle, fileUploadField, fileStorageUploadField, upload, notificationsIndicator, webdavDocumentUpload, menu.xml<menu> и <item> поддерживают <icon>).

Подробнее см. в разделе Иконки.

Поддержка H2 Database (Experimental)

Добавлена экспериментальная поддержка базы данных H2. Теперь вы можете выбрать H2 File или H2 Server в выпадающем списке Database type редактора свойств хранилища данных.

Во время разработки можно использовать свойство приложения spring.h2.console.enabled=true для включения веб-консоли базы данных. Консоль будет доступна по адресу http://localhost:8080/h2-console.

Кастомные сервисы обновления (Experimental)

Универсальный REST API, Инспектор сущностей и BPM Entity Data Task теперь могут делегировать операции сохранения и удаления кастомному сервису приложения вместо прямого вызова DataManager. Это позволяет поместить логику обновления сущностей в сервис и быть уверенным, что она будет вызвана из общих функций фреймворка. Ранее для этого приходилось использовать слушатели EntityChangedEvent.

Для вызова фреймворком кастомный сервис должен реализовывать следующие интерфейсы:

public interface SaveDelegate<E> {

    /**
     * Called by generic framework mechanisms instead of {@code DataManager} when saving entities of type {@code E}.
     *
     * @param entity entity to save
     * @param saveContext the whole save context
     * @return saved entity
     */
    E save(E entity, SaveContext saveContext);
}

public interface RemoveDelegate<E> {
    /**
     * Called by generic framework mechanisms instead of {@code DataManager} when removing entities of type {@code E}.
     *
     * @param entity entity to remove
     */
    void remove(E entity);
}

Критические изменения

Механизм регистрации и загрузки фасетов

Механизм FacetProvider для регистрации фасетов теперь объявлен устаревшим (deprecated) и будет удален в одной из будущих версий. Существующие пользовательские фасеты, зарегистрированные с помощью FacetProvider, продолжают работать благодаря обратной совместимости. Однако настоятельно рекомендуется выполнить миграцию на новый API FacetRegistrationBuilder. Смотрите Пользовательские фасеты.

Критическое изменение затрагивает стандартные переопределения фасетов Jmix. Если вы ранее переопределяли фасеты фреймворка, используя старый механизм, эти переопределения перестанут работать после обновления. Такие пользовательские реализации необходимо переопределить заново, используя новый API:

@Configuration
public class FacetConfiguration {

    @Bean
    public FacetRegistration extTimerFacet() {
        return FacetRegistrationBuilder.create(MyOverridenFacet.class)
                .replaceFacet(OriginalFacet.class)
                .build();
    }
}

Изменения в API фасетов

Этот релиз включает несколько улучшений API фасетов для лучшей поддержки фрагментов и предоставления более чистых абстракций.

Изменения типа владельца фасета

Методы Facet.getOwner() и Facet.setOwner() были обновлены для поддержки фрагментов в качестве владельцев:

  • Facet.getOwner() теперь возвращает <T extends Composite<?> & FacetOwner> T (ранее возвращал View<?>)

  • Сигнатура Facet.setOwner() изменена на <T extends Composite<?> & FacetOwner> void setOwner(@Nullable T owner) (ранее void setOwner(@Nullable View<?> owner))

Ранее владельцем фасета мог быть только View. Теперь любой компонент, реализующий оба интерфейса Composite<?> и FacetOwner, может выступать в роли владельца фасета. Это изменение позволяет фасетам работать с фрагментами, так как Fragment реализует оба интерфейса.

Если ваш код напрямую вызывает эти методы, обновите типы соответствующим образом.

Рефакторинг классов фасетов

Конкретные классы реализации (*Impl) были заменены на абстрактные базовые классы:

  • DataLoadCoordinatorImplAbstractDataLoadCoordinator

  • SettingsFacetImplAbstractSettingsFacet<S extends UiComponentSettings<S>>

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

Параметризация интерфейсов настроек

Интерфейсы настроек теперь параметризованы для повышения безопасности типов:

  • SettingsFacetSettingsFacet<S extends UiComponentSettings<S>>

  • SettingsContextSettingsContext<S extends UiComponentSettings<S>>

Если вы реализуете пользовательский SettingsFacet или используете SettingsContext, добавьте обобщенный параметр:

// До:
public class MySettingsFacet implements SettingsFacet

// После:
public class MySettingsFacet implements SettingsFacet<MyUiComponentSettings>

Для получения более подробной информации смотрите соответствующий тикет: #4185.

Области действия ролей в OIDC и Authorization Server

Исправлена обработка областей действия ролей в дополнении OpenID Connect. Вы можете использовать свойства приложения jmix.oidc.filter-chain.force-ui-scope-enabled и jmix.oidc.filter-chain.force-api-scope-enabled для возврата к предыдущему поведению.

Если вы использовали свойство jmix.resource-server.force-api-security-scope.enabled в Jmix 2.7, замените его на свойство jmix.authserver.filter-chain.force-api-scope-enabled со значением false.

См. #5094 для получения дополнительной информации.

MariaDB UUID

Для совместимости со всеми предыдущими и текущими версиями MariaDB и Liquibase, для атрибутов UUID теперь явно используется char(36).

Если вы используете MariaDB, следуйте инструкциям ниже после обновления вашего проекта до Jmix 2.8.

  1. Чтобы избежать ошибки контрольной суммы Liquibase для выполненных changelog, запустите ваше приложение один раз со свойством main.liquibase.clear-checksums=true. Например, если ваше основное хранилище данных использует MariaDB, выполните следующую команду:

    ./gradlew bootRun --args='--main.liquibase.clear-checksums=true'

    После выполнения Liquibase на вашей базе данных с этой опцией контрольные суммы в БД будут обновлены и совместимы с changelog’ами, расположенными в вашем исходном коде.

    Не используйте main.liquibase.clear-checksums=true для последующих запусков.

  2. Убедитесь, что корневой changelog (например, com/company/sample/liquibase/changelog.xml) включает в себя следующее свойство:

    <property name="uuid.type" dbms="mariadb" value="char(36)"/>
  3. Убедитесь, что новые сгенерированные changelog используют ${uuid.type} или char(36) для атрибутов UUID. Например:

    <changeSet id="1" author="sample">
        <createTable tableName="FOO">
            <column name="ID" type="${uuid.type}">

См. #4838 для получения дополнительной информации.

Список изменений

  • Решенные проблемы в Jmix Framework:

  • Решенные проблемы в Jmix Studio: