Что нового
В данном разделе приведена информация о новой функциональности и возможных несовместимых изменениях в фреймворке Jmix и Jmix Studio версии 2.8. Примите их во внимание при обновлении с предыдущей версии фреймворка.
|
Для создания новых проектов в Jmix 2.8 или для апгрейда существующего проекта требуется Studio 2.8 или более поздней версии, поэтому в первую очередь обновите плагин Jmix Studio. Минимальная требуемая версия IntelliJ IDEA / OpenIDE - 2025.3. |
Раздел Апгрейд проекта содержит информацию о том, как обновить проект с помощью Studio. Процедура автоматической миграции вносит следующие изменения в ваш проект:
-
Обновляет версию Jmix BOM, которая, в свою очередь, определяет версии всех зависимостей.
-
Обновляет версию Jmix Gradle plugin.
-
Обновляет версию Gradle wrapper до 8.14.4
См. полный список критических изменений, которые могут затронуть ваш проект после обновления.
Новая и улучшенная функциональность
Улучшения Studio
Дополнительные пакеты сообщений
Если вы определили дополнительные пакеты сообщений в вашем проекте, Studio теперь позволит вам выбрать пакет при редактировании сообщения в диалоговом окне Localized Message.
Поддержка переменных окружения с помощью .env файлов
Studio теперь поддерживает использование .env файлов для вынесения конфигурации за пределы приложения. Вы можете хранить переменные, специфичные для окружения, отдельно от application.properties и использовать их с плейсхолдерами, такими как ${DB_URL}.
Подробнее смотрите в разделе Внешняя конфигурация с использованием .env файлов.
Игнорирование внешнего ключа в changelog
Studio теперь учитывает ограничения JPA при генерации changelog для ассоциаций. Если задать ConstraintMode.NO_CONSTRAINT в @JoinColumn, внешний ключ не будет добавлен в сгенерированный changelog. Подробнее см. в разделе Игнорирование внешнего ключа.
Дополнение SAML
Дополнение Jmix SAML добавляет аутентификацию SAML 2.0 в приложениях Jmix. С этим дополнением приложение Jmix может выступать в роли поставщика услуг (service provider) и использовать внешний поставщик удостоверений (identity provider), такой как Keycloak, Okta, Microsoft Entra ID и другие, для аутентификации пользователей.
Подробности по настройке и конфигурации скоро будут доступны в разделе Дополнение SAML.
Метки дней в бизнес-календаре
Ранее дополнение Business Calendars позволяло добавлять описания только для праздников. Теперь вы можете добавить метку (mark) для любой записи календаря. Это упрощает категоризацию и позволяет указать, почему у конкретной даты могут отличаться рабочие часы. Также появились новые методы API, с помощью которых можно получить информацию о конкретной дате, включая назначенную метку.
Подробнее см. в Создание бизнес-календаря.
Экран Process Drafts
Дополнение BPM теперь предоставляет специальный экран для предварительного просмотра черновиков процессов. Ранее черновики были доступны только через диалог в экране Modeler и не поддерживали предварительный просмотр.

Подробнее см. в Process Drafts.
Визуализация прогресса на диаграммах экземпляров процесса
Дополнение BPM выделяет завершённые действия на диаграммах экземпляров процесса зелёным цветом, делая прогресс выполнения более наглядным.

Диаграмма доступна на экране Process Instances.
Динамические атрибуты в формах процесса
В дополнении BPM, процессные формы на базе экранов Jmix поддерживают загрузку и отображение динамических атрибутов. Для этого используйте аннотацию @ProcessVariableParam. Подробнее см. в разделе Загрузка динамических атрибутов.
Визуализация модели данных
Дополнение Data Tools теперь включает экран Data Model для просмотра сущностей и их атрибутов в запущенном приложении. Экран также позволяет создать диаграмму модели данных (для всех сущностей или лишь для выбранного набора), используя публичный или собственный сервер PlantUML.
Поддержка коллекций элементов
Модель данных Jmix теперь поддерживает коллекции базовых типов, объектов FileRef или кастомных типов. В JPA-сущностях эти атрибуты-коллекции аннотируются с помощью @ElementCollection и хранятся в отдельных таблицах базы данных.
См. раздел Сущности о том, как определять коллекции элементов, и Работа с DataManager о том, как использовать их в запросах.
Атрибуты-коллекции элементов по умолчанию загружаются лениво и могут быть включены в фетч-планы при необходимости.
Атрибуты-коллекции элементов могут использоваться в условиях компонента genericFilter и могут быть привязаны как значения компонентов multiValuePicker, multiSelectComboBox и multiSelectComboBoxPicker.
Чтобы создать атрибут-коллекцию элементов в Studio, выберите ELEMENT_COLLECTION в раскрывающемся списке Attribute type диалога New Attribute.
См. также #1271.
Фасеты во фрагментах
Фрагменты теперь поддерживают фасеты. См. раздел Фасеты во фрагментах об их использовании, и информацию о связанных критических изменениях ниже:
Компоновка с боковой панелью
Новый компонент sidePanelLayout предоставляет декларативный способ создания компоновок с выдвижной боковой панелью. Он позволяет отображать вспомогательное содержимое или действия без перехода с текущего экрана.

Боковая панель может открываться с разных сторон и либо перекрывать основной контент, либо сдвигать его. Подробности и примеры использования см. в sidePanelLayout.
Боковое диалоговое окно
API Dialogs добавляет возможность использовать диалог в качестве боковой панели — UI-паттерн, похожий на sidePanelLayout, но создаваемый программно. SideDialog создает диалог, прикрепленный к одной из сторон экрана.

Используйте его для взаимодействий, которые не требуют встраивания в основную компоновку экрана. Подробнее и пример использования см. в SideDialog.
Поддержка пользовательских иконок в компонентах
Многие компоненты теперь позволяют добавлять пользовательские иконки через вложенные элементы. Эти элементы обозначают конкретные слоты для иконок в компоненте — например, <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>).
Подробнее см. в разделе Иконки.
Механизм переопределения стандартных иконок
Теперь вы можете централизованно менять иконки во всём приложении. Перечисление JmixFontIcon объединяет иконки Vaadin, отсутствующие в Vaadin иконки Lumo, а также иконки Jmix в единый набор. Новый бин Icons предоставляет единый интерфейс для создания UI компонентов, предоставляющих иконки. Замена иконок осуществляется путём переопределения CSS‑переменных либо замены иконочного шрифта.
Подробнее см. в разделе Замена стандартных иконок.
Трассировка
Jmix теперь использует Micrometer Observation API для создания спанов для операций фреймворка, таких как доступ к данным, жизненный цикл экранов и фрагментов UI, действия UI. Jmix также может добавлять в наблюдения контекст текущего пользователя и арендатора.
Подробнее см. в разделе Наблюдаемость: Трассировка.
Поддержка 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) были заменены на абстрактные базовые классы:
-
DataLoadCoordinatorImpl→AbstractDataLoadCoordinator -
SettingsFacetImpl→AbstractSettingsFacet<S extends UiComponentSettings<S>>
Если вы ранее создавали экземпляры этих классов напрямую, перейдите на использование внедрения зависимостей или новых абстрактных классов.
Параметризация интерфейсов настроек
Интерфейсы настроек теперь параметризованы для повышения безопасности типов:
-
SettingsFacet→SettingsFacet<S extends UiComponentSettings<S>> -
SettingsContext→SettingsContext<S extends UiComponentSettings<S>>
Если вы реализуете пользовательский SettingsFacet или используете SettingsContext, добавьте обобщенный параметр:
// До:
public class MySettingsFacet implements SettingsFacet
// После:
public class MySettingsFacet implements SettingsFacet<MyUiComponentSettings>
Для получения более подробной информации смотрите соответствующий тикет: #4185.
Методы getIcon() возвращающие Icon объявлены устаревшими
В этом релизе добавлен бин Icons для поддержки механизма замены стандартных иконок. При разборе XML-атрибутов бин создает компонент FontIcon для значений в которых не указан набор иконок; для значений, где набор указан – создаётся Icon. Например:
-
icon="CHECK"создаёт компонентFontIcon, -
icon="vaadin:check"создаёт компонентIcon.
В связи с этим методы getIcon(), возвращающие Icon, объявлены устаревшими. Если иконка задана без имени коллекции такой метод вернёт null. Используйте getIconComponent() для получения компонента иконки.
View Routes
Маршруты всех экранов, предоставляемых подсистемами Jmix, изменены на kebab-case. Например: sec/resourcerolemodels → sec/resource-role-models. Для обратной совместимости старые маршруты определены как псевдонимы, поэтому все сохраненные внешние ссылки должны работать.
Если вы переопределили какой-либо экран фреймворка и скопировали аннотацию @Route в класс вашего экрана, удалите ее. В противном случае экран не зарегистрируется, и приложение не запустится.
См. #4841 для получения дополнительной информации.
Области действия ролей в 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.
-
Устраните ошибки контрольной суммы Liquibase для выполненных changelog. Это можно сделать одним из двух следующих способов:
-
Запустите ваше приложение один раз со свойством
main.liquibase.clear-checksums=true. Например, если ваше основное хранилище данных использует MariaDB, выполните следующую команду:./gradlew bootRun --args='--main.liquibase.clear-checksums=true'В качестве альтернативы можно добавить
main.liquibase.clear-checksums=trueв файлapplication.propertiesи собрать специальную версию вашего приложения, чтобы запустить его один раз на продакшен базе данных.После выполнения Liquibase на вашей базе данных с этой опцией контрольные суммы в БД будут обновлены и совместимы с changelog’ами, расположенными в вашем исходном коде.
Не используйте
main.liquibase.clear-checksums=trueдля последующих запусков. -
Вместо очистки контрольных сумм вы можете установить валидные значения в changelog-файлах. Для каждого changeset, использующего переменную
uuid.type, установитеvalidCheckSumв значение, которое в настоящее время присутствует в колонкеMD5SUMтаблицыDATABASECHANGELOG. Например:<changeSet id="1" author="admin"> <validCheckSum>9:c2f20bd9d8765d4c2554826e5eb376a8</validCheckSum> <!--...--> </changeSet>
-
-
Убедитесь, что корневой changelog (например,
com/company/sample/liquibase/changelog.xml) включает в себя следующее свойство:<property name="uuid.type" dbms="mariadb" value="char(36)"/> -
Убедитесь, что новые сгенерированные changelog используют
${uuid.type}илиchar(36)для атрибутовUUID. Например:<changeSet id="1" author="sample"> <createTable tableName="FOO"> <column name="ID" type="${uuid.type}">
См. #4838 для получения дополнительной информации.