YAML Reference

The dynamic model is serialized as YAML under a model: root key. This page documents the schema in full: every field, its type, whether it is required, its default value, and the rules that govern it. For task-oriented guidance, see Defining the Model and Views and Menu Items.

Model

The model root contains these top-level fields:

Field Type Required Notes

basePackage

string

no

Java package for generated dynamic entity, enum, and view classes. If omitted or blank, the effective value is the last Jmix module base package plus .dynmod. The field is omitted on serialization when it equals the default.

enumerations

list

no

Dynamic enum definitions. Missing or null becomes an empty list.

entities

list

no

Static entity extensions and dynamic entity definitions. Missing or null becomes an empty list.

Names and Resolution

Entity definitions are matched by Jmix entity name:

  • If an entity with name already exists in metadata, the definition extends that static entity with dynamic attributes, validation, uniqueness, or view overrides.

  • If no metadata entity exists, Dynamic Model creates a dynamic entity with the same Jmix entity name and a generated Java class named <effective basePackage>.<name>.

Use Java-like names for dynamic entities, attributes, enum classes, and enum values. Generated database identifiers are normalized automatically:

  • camel case is split to upper underscore names, for example loyaltyLevel becomes LOYALTY_LEVEL;

  • unsupported characters are replaced with underscores;

  • reserved words receive a trailing underscore, for example user becomes USER_;

  • identifiers exceeding the DBMS limit are shortened with an 8-character hash.

Localization Values

Most captions use a plain locale-to-message map:

messages:
  en: "Loyalty level"
  de: "Treuestufe"

Some fields are localized values and accept either a plain string:

viewTitle: "Benefit"

or a locale map:

viewTitle:
  en: "Loyalty levels"
  de: "Treuestufen"

Locale keys must be non-blank and map to strings. At runtime, the exact locale is preferred, then the language-only locale, then the first map value.

Enumerations

Dynamic enumerations are declared in model.enumerations:

enumerations:
  - name: "CustomerGrade"
    messages:
      en: "Customer grade"
    values:
      - name: "PLATINUM"
        id: "30"
        messages:
          en: "Platinum"
      - name: "GOLD"
        id: "20"
        messages:
          en: "Gold"
      - name: "BRONZE"
        id: "10"
        messages:
          en: "Bronze"

Enum fields:

Field Type Required Notes

name

string

yes

Short class name or fully qualified class name. Short names are resolved against basePackage.

values

list

yes

Must contain at least one value.

messages

map

no

Captions for the enum class.

Enum value fields:

Field Type Required Notes

name

string

yes

Java enum constant name.

id

string

yes

Stored enum ID. All IDs in one dynamic enum must be homogeneous: either all parse as 32-bit integers or all are non-integer strings.

messages

map

no

Captions for this enum value.

Dynamic enums implement EnumClass<Integer> when all IDs are integer strings, otherwise EnumClass<String>.

Attribute references to enums use the enumeration field:

- name: "grade"
  enumeration: "CustomerGrade" # short name, resolved via base package
  messages:
    en: "Grade"

Static enums are also supported if the class implements EnumClass. Use a fully qualified class name, or a short name when the enum class is in basePackage. Enum DB mapping supports both integer IDs and string IDs.

Entities

Entity definitions are declared in model.entities:

- name: "Benefit"
  messages:
    en: "Benefit"
  attributes:
    - name: "name"
      javaClass: "java.lang.String"
      instanceName: true
      messages:
        en: "Name"
  views:
    - type: "detail"
      viewId: "Benefit.detail"
      viewTitle: "Benefit"
      descriptor:
        template: "default"
Field Type Required Notes

name

string

yes

Jmix entity name. An existing metadata name means a static entity extension; otherwise a dynamic entity is created.

store

string

no

Physical JPA data store for dynamic entities. Blank and main are serialized as omitted. Static entity definitions may declare a store only if it matches the entity metadata store. An existing dynamic entity store cannot be changed.

attributes

list

no

Dynamic attributes. Missing or null becomes an empty list.

uniqueConstraints

list

no

Named entity-level unique constraints.

views

list

no

Entity-owned UI views.

resourceRoles

object

no

Entity CRUD role grants. Supported only for dynamic entities.

validation

object

no

Entity-level validation constraints.

messages

map

no

Entity captions.

Dynamic entity tables use the configurable jmix.dynmodel.dynamic-entity-table-prefix prefix, default DYN_. Static entity dynamic attributes are stored in side tables using jmix.dynmodel.static-entity-table-prefix, default DYN_. Static side tables are created in the same physical store as the static owner entity.

Attributes

Every attribute must define exactly one kind:

  • datatype: javaClass;

  • reference: entityName;

  • enum: enumeration.

- name: "Customer"
  attributes:
    - name: "taxId"
      javaClass: "java.lang.String"
      length: 20
      required: true
      unique: true
      validation:
        constraints:
          - annotation: "Pattern"
            parameters:
              regexp: "^[A-Z0-9-]+$"
            message:
              en: "Tax ID can contain uppercase letters, digits and dashes only"
      messages:
        en: "Tax ID"
Field Type Required Notes

name

string

yes

Attribute name.

javaClass

string

kind

Java class for datatype attributes. See supported values below.

entityName

string

kind

Target Jmix entity name for references and collections.

enumeration

string

kind

Dynamic or static enum name. Short names are resolved through basePackage.

length

integer

no

Length for strings, URI values, byte arrays, and string-ID enums.

lob

boolean

no

LOB indicator. Supported only for java.lang.String and byte[] attributes.

required

boolean

no

Adds mandatory metadata and a default-group NotNull validation rule. Does not create a DB NOT NULL constraint.

unique

boolean

no

Shorthand for a single-attribute unique constraint named <attributeName>Unique.

instanceName

boolean

no

Marks the attribute as an instance-name property. If several attributes are marked, the first one is used and later ones are ignored with a warning.

collection

boolean

no

Makes an entityName reference an ordered composition list.

calculated

object

no

Makes the attribute read-only and non-persistent.

validation

object

no

Attribute-level constraints. Not allowed on calculated attributes.

resourceRoles

object

no

Attribute view/modify grants.

messages

map

no

Attribute captions.

Supported javaClass Values

Persistent datatype attributes are mapped to SQL types by the framework. Use these values when writing YAML manually:

YAML value Java type Default SQL mapping

java.lang.String

String

varchar(255); length overrides size

java.net.URI

URI

varchar(1024); length overrides size

[B

byte[]

varbinary(255); length overrides size

java.lang.Boolean or boolean

Boolean

boolean

java.lang.Character or char

Character

char(1)

java.lang.Integer or int

Integer

integer

java.lang.Long or long

Long

bigint

java.lang.Short or short

Short

smallint

java.lang.Double or double

Double

double

java.lang.Float or float

Float

real

java.math.BigDecimal

BigDecimal

decimal(38, 18)

java.math.BigInteger

BigInteger

decimal(38, 0)

java.time.LocalDate

LocalDate

date

java.time.LocalTime

LocalTime

time

java.time.LocalDateTime

LocalDateTime

timestamp

java.time.OffsetTime

OffsetTime

time with time zone

java.time.OffsetDateTime

OffsetDateTime

timestamp with time zone

java.util.UUID

UUID

DB-specific UUID type

Notes:

  • The serializer stores Java Class#getName() values. For a byte array this is [B; copy the serialized value if unsure.

  • Other Java classes are not supported by Dynamic Model storage unless DB type mapping is extended.

DB-specific deviations:

Type HSQLDB / H2 PostgreSQL MySQL / MariaDB SQL Server Oracle

UUID

uuid

uuid

char(32)

uniqueidentifier

char(32)

String

varchar(n)

varchar(n)

varchar(n)

nvarchar(n)

varchar2(n)

byte[]

varbinary(n)

bytea

varbinary(n)

varbinary(n)

raw(min(n, 2000))

Boolean

boolean

boolean

bit

bit

char(1)

OffsetTime

time with time zone

time with time zone

time stored in UTC

datetimeoffset

timestamp with time zone

OffsetDateTime

timestamp with time zone

timestamp with time zone

datetime stored in UTC

datetimeoffset

timestamp with time zone

String + lob: true

clob

text

longtext

nvarchar(max)

clob

byte[] + lob: true

blob

bytea

longblob

varbinary(max)

blob

References

Single-valued references use entityName:

- name: "loyaltyLevel"
  entityName: "LoyaltyLevel"
  messages:
    en: "Loyalty level"

Rules:

  • The target must resolve to a dynamic entity declared in the model or to an existing static entity.

  • Dynamic references store the target primary key value.

  • Static targets with composite primary keys are not supported.

  • Owner and target must be in the same physical store.

Collections

Collection attributes are ordered composition lists:

- name: "benefits"
  entityName: "Benefit"
  collection: true
  messages:
    en: "Benefits"

Rules:

  • entityName is required.

  • The target must be a dynamic entity.

  • javaClass, enumeration, lob, and instanceName are not supported.

  • Collections cannot participate in unique constraints.

  • Owner and target must be in the same physical store.

  • Static owners with composite primary keys are not supported.

Dynamic Model creates internal child properties for the inverse owner reference and order column. They are not written to YAML.

Calculated Attributes

Calculated attributes are read-only, non-persistent properties evaluated on access:

- name: "publicSummary"
  javaClass: "java.lang.String"
  calculated:
    evaluator: "spel"
    expression: "(name ?: '') + ': ' + (description ?: '')"
    dependsOn:
      - "name"
      - "description"
  messages:
    en: "Public summary"
Field Type Required Notes

evaluator

string

no

Evaluator name returned by a DynamicCalculatedAttributeEvaluator bean from getName(). If omitted or blank, jmix.dynmodel.calculated-attributes.default-evaluator is used, then spel.

expression

string

yes

Evaluator-specific expression. The built-in spel evaluator uses a restricted SimpleEvaluationContext.

dependsOn

list

no

Immediate property names to load with the calculated attribute. Dotted paths are rejected. Missing or null becomes an empty list.

Rules:

  • A calculated attribute must declare exactly one result type using javaClass or enumeration.

  • entityName, collection, required, validation, and uniqueness are not supported.

  • lob: true is only a UI metadata hint and still requires javaClass to be java.lang.String or byte[].

  • Dependencies must exist on the same entity, either in the current model or in existing metadata.

  • Cycles between calculated attributes in one entity are rejected.

  • Changing an existing stored attribute to calculated, or an existing calculated attribute to stored, is not supported. Changing the calculated result type is also not supported.

The built-in SpEL evaluator allows metadata-aware property reads and registered DynamicCalculatedAttributeFunction functions. It does not expose Spring beans, T(…​), constructors, arbitrary method calls, reflection, classloader access, or infrastructure APIs.

Attribute Validation

Attribute validation is declared under attributes[].validation.constraints:

validation:
  constraints:
    - annotation: "Pattern"
      parameters:
        regexp: "^[A-Z0-9-]+$"
      message:
        en: "Tax ID can contain uppercase letters, digits and dashes only"

Constraint fields:

Field Type Required Notes

annotation

string

yes

Constraint alias. See supported aliases below.

parameters

map

no

YAML scalar/list/object values. Parameter names depend on the constraint. Missing becomes an empty map.

groups

list

no

Group aliases or fully qualified validation group class names. Missing means Default.

message

localized value

no

Plain string or locale map.

Supported groups:

  • Default;

  • UiComponentChecks;

  • UiCrossFieldChecks;

  • RestApiChecks;

  • fully qualified class names resolvable by Class.forName().

Supported attribute constraints:

Alias Applies to Parameters

NotNull

any attribute

none

NotEmpty

strings, collections, arrays

none

NotBlank

strings

none

Size

strings, collections, arrays

min optional, default 0; max optional, default Integer.MAX_VALUE

Length

strings

min optional, default 0; max optional, default Integer.MAX_VALUE

Min

numeric

value

Max

numeric

value

DecimalMin

numeric

value; inclusive optional boolean, default true

DecimalMax

numeric

value; inclusive optional boolean, default true

Digits

numeric

integer; fraction

Positive

numeric

none

PositiveOrZero

numeric

none

Negative

numeric

none

NegativeOrZero

numeric

none

Past

date/time

none

PastOrPresent

date/time

none

Future

date/time

none

FutureOrPresent

date/time

none

Pattern

strings

regexp

Email

strings

none

AssertTrue

booleans

none

AssertFalse

booleans

none

Validation uses Bean Validation null semantics: null is valid unless the rule is NotNull, NotEmpty, NotBlank, AssertTrue, or AssertFalse.

required: true is equivalent to mandatory UI metadata plus a default-group NotNull rule. Validation metadata does not create DB constraints.

Entity Validation

Entity-level validation is declared under entities[].validation.constraints:

validation:
  constraints:
    - name: "discountDescriptionRequired"
      target: "entity"
      type: "expression"
      evaluator: "spel"
      expression: "discount == null || description != null"
      attributes:
        - "discount"
        - "description"
      path: "description"
      groups:
        - "UiCrossFieldChecks"
        - "RestApiChecks"
      message:
        en: "Description is required when discount is specified"
Field Type Required Notes

name

string

no

Constraint name for diagnostics.

target

string

yes

Must be entity.

type

string

yes

expression or bean.

evaluator

string

expression

Built-in expression evaluator is spel. Blank also resolves to spel.

expression

string

expression

Must evaluate to true for valid entities.

validator

string

bean

Name returned by a DynamicModelConstraintValidator bean.

attributes

list

no

Participating attribute names. Each name must exist in the model or metadata.

path

string

no

Violation property path. Blank means a bean-level violation.

groups

list

no

Same group aliases as attribute validation.

message

localized value

no

Plain string or locale map.

Expression constraints use the same restricted SpEL property access approach as calculated attributes. Bean constraints delegate to application DynamicModelConstraintValidator beans.

Unique Constraints

Single-attribute uniqueness:

unique: true

Composite uniqueness:

uniqueConstraints:
  - name: "customerCountryTaxIdUnique"
    attributes:
      - "countryCode"
      - "taxId"
    message:
      en: "Tax ID must be unique within a country"
Field Type Required Notes

name

string

yes

Logical constraint name. Must be non-blank and unique within the entity. The physical DB name is generated from the table name plus this value.

attributes

list

yes

At least one direct dynamic attribute. Duplicate names are rejected.

message

localized value

no

Violation message.

Rules:

  • attributes[].unique: true is normalized to a named entity-level constraint before comparison and DDL planning.

  • Only direct persistent single-valued dynamic attributes can participate.

  • Calculated attributes, collections, and LOB attributes are rejected.

  • Static soft-deletable owners are not supported.

  • Applying a new unique constraint fails if existing rows already contain duplicates.

  • Nullable uniqueness follows the target DBMS behavior.

Resource Roles

Dynamic resourceRoles declarations create additive resource policies at runtime. Omitted declarations do not grant access. Roles listed in jmix.dynmodel.security.full-access-roles grant full access to all dynamic model resources; the default is system-full-access.

Role codes must be non-blank. Missing role codes are logged and do not grant access.

Entity-level CRUD grants are supported only for dynamic entities:

resourceRoles:
  read:
    - "employee"
    - "manager"
  create:
    - "manager"
  update:
    - "manager"
  delete:
    - "manager"

Attribute grants are supported on dynamic attributes of both static and dynamic entities:

- name: "countryCode"
  javaClass: "java.lang.String"
  length: 2
  resourceRoles:
    view:
      - "employee"
      - "manager"
    modify:
      - "manager"
  messages:
    en: "Country code"

View and menu grants are lists:

views:
  - type: "list"
    viewId: "LoyaltyLevel.list"
    viewRoute: "loyalty-levels"
    viewTitle:
      en: "Loyalty levels"
      de: "Treuestufen"
    templateParams:
      includeProperties: ["name", "discount"]
      excludeProperties: ["publicSummary"]
    resourceRoles:
      - "employee"
      - "manager"
    menuItem:
      parentMenu: "application"
      insertBefore: "Customer.list"
      title:
        en: "Loyalty levels"
      resourceRoles:
        - "employee"
        - "manager"
    descriptor:
      template: "default"

Views

Views are declared under entities[].views.

views:
  - type: "list"
    viewId: "LoyaltyLevel.list"
    viewRoute: "loyalty-levels"
    viewTitle:
      en: "Loyalty levels"
      de: "Treuestufen"
    templateParams:
      includeProperties: ["name", "discount"]
      excludeProperties: ["publicSummary"]
    resourceRoles:
      - "employee"
      - "manager"
    menuItem:
      parentMenu: "application"
      insertBefore: "Customer.list"
      title:
        en: "Loyalty levels"
      resourceRoles:
        - "employee"
        - "manager"
    descriptor:
      template: "default"

View fields:

Field Type Required Notes

type

string

dynamic entities

list or detail. Case-insensitive during deserialization. Required for dynamic entity views. Static entity views can infer it from the registered base view.

viewId

string

yes

Unique view ID. Dynamic and static view declarations should set it explicitly.

viewRoute

string

no

Dynamic entity route segment. Defaults to a slug made from viewId; detail views append /:id. Static entity views do not support this field.

viewTitle

localized value

no

Dynamic entity view title. Static entity views do not support this field.

templateParams

map

no

Dynamic entity template parameters. Static entity views do not support this field.

resourceRoles

list

no

Role codes that can open the view. Static entity views do not support this field.

menuItem

object

no

Dynamic entity menu item. Static entity views do not support this field.

descriptor

object

static entities

Descriptor declaration. Dynamic entity views can omit it to use the default template. Static entity views must provide descriptor.source.

lookupComponentId

string

no

Dynamic list view lookup component ID. Default is dataGrid. Static entity views do not support this field.

editedEntityContainerId

string

no

Dynamic detail view edited entity container ID. Default is entityDc. Static entity views do not support this field.

Dynamic Entity Views

Rules:

  • type must be list or detail.

  • viewId must be set explicitly and must be unique.

  • If viewRoute is omitted, it is generated from viewId by lowercasing and replacing non-alphanumeric sequences with -.

  • Detail routes automatically append /:id; therefore viewRoute itself must not end with /:id.

  • The first declared list view becomes the primary list view for the dynamic entity. The first declared detail view becomes the primary detail view.

  • descriptor may be omitted, use template: "default", use a custom template resource path, or provide literal source.

  • If descriptor.source is used, it must be valid XML with root <view xmlns="http://jmix.io/schema/flowui/view">.

  • Explicit list descriptors must contain the lookup component ID, default dataGrid.

  • Explicit detail descriptors must contain the edited entity container ID, default entityDc.

Default templates are:

  • io/jmix/flowui/view/template/list-view.ftl for list views;

  • io/jmix/flowui/view/template/detail-template.ftl for detail views.

templateParams is a YAML object passed to descriptor template rendering. Dynamic Model does not define a fixed schema for it; supported keys depend on the selected template. For example, a template can consume list-of-string property filters:

templateParams:
  includeProperties: ["name", "discount"]
  excludeProperties: ["publicSummary"]

Static Entity View Overrides

Static entity view declarations override the XML descriptor of an already registered view:

- viewId: "Customer.list"
  descriptor:
    source: |
      <?xml version="1.0" encoding="UTF-8" standalone="no"?>
      <view xmlns="http://jmix.io/schema/flowui/view"
            extends="com/company/sample/view/customer/customer-list-view.xml">
          <layout>
              <dataGrid id="customersDataGrid">
                  <columns>
                      <column property="taxId"/>
                  </columns>
              </dataGrid>
          </layout>
      </view>

Rules:

  • viewId is required and must reference a registered static view.

  • type may be omitted; it is inferred from the controller class.

  • Only descriptor.source is supported.

  • descriptor.template, viewRoute, viewTitle, templateParams, resourceRoles, menuItem, lookupComponentId, and editedEntityContainerId are rejected.

  • The generated controller subclasses the current registered controller and preserves its route.

Descriptor

descriptor must contain exactly one of:

descriptor:
  template: "default"

or:

descriptor:
  source: |
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <view xmlns="http://jmix.io/schema/flowui/view"
          extends="com/company/sample/view/customer/customer-list-view.xml">
        <layout>
            <dataGrid id="customersDataGrid">
                <columns>
                    <column property="taxId"/>
                </columns>
            </dataGrid>
        </layout>
    </view>

menuItem fields:

Field Type Required Notes

parentMenu

string

yes

Existing or new parent menu ID. If not found, a root menu with this ID is created.

insertBefore

string

no

Insert before a sibling menu ID when found; otherwise append.

title

localized value

no

Defaults to the view title when omitted.

resourceRoles

list

no

Role codes that can access the menu item.

Detail view menu items receive the route parameter id=new.