Defining the Model

The Dynamic model → Dynamic model settings view provides an admin UI for editing the dynamic model. You add entities, attributes, enumerations, and other elements through the visual editor, then Apply the changes to validate them and publish a new model version.

Each topic below shows the YAML that the editor produces for the corresponding element — this is the same definition you can view and edit directly in the editor’s YAML view.

See Concepts for how applying a model works and how versions are managed, and YAML Reference for the full reference of every element.

Using the Model Editor

Open the Dynamic model settings view. The Visual editor presents the current model as a structure of linked tables with entities, attributes, enumerations, views. You can add and edit elements using dialogs.

You can switch to the Code presentation at any time to inspect or edit the raw YAML definition directly; the two presentations stay in sync.

When the model is ready, click Apply. The framework compares the edited model with the currently active one and opens the intermediate Dynamic model changes view, which shows what will be applied before anything is committed. Under Model migrations it lists each individual change — such as creating an entity, adding or removing an attribute, or adding a unique constraint. If any views are affected, they are listed under Changed views.

Review the list and click Apply changes to confirm. The model is validated and, if valid, the changes are applied and published as a new model version that becomes active immediately. Closing the Dynamic model changes view without applying discards the pending changes and leaves the active model unchanged.

Attribute Order

Since Jmix 3.1

On the Attributes tab, select an attribute and use the Move the attribute up and Move the attribute down buttons to change its position. The order of attributes is saved in the model. It defines the order of fields in generated detail views and of columns in generated list views, and the order of properties in metadata, which is used by the REST API, the entity inspector and the generic filter. The new order takes effect when you apply the model.

Only dynamic attributes can be moved. The own properties of a static entity and the identifier of a dynamic entity keep their positions. The order of columns in the database does not change.

Model History

Since Jmix 3.1

In the Code presentation, click History to see all saved versions of the model, newest first. For each version, the dialog shows the date, the user who applied it, and whether it is the active one. Select a version to see its YAML, and click Copy to clipboard to copy it.

The dialog does not apply an earlier model. To return to an earlier version, copy its YAML, paste it into the Code presentation, and apply the model.

Extending Static Entities

To add dynamic attributes to an entity that already exists in your application (a static entity such as Customer), select that entity in the editor and add attributes to it. The dynamic attributes are stored separately from the entity’s own table and become available alongside the static attributes at runtime.

The example below adds a taxId string attribute to Customer, with length 20, a required flag, uniqueness, and a validation rule:

- 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"

Defining Dynamic Entities

A dynamic entity is a brand-new entity that exists only at runtime — it has no Java class or table in your source code. To create one, add an entity in the editor whose name does not match any existing entity, then define its attributes and, optionally, its views. See Views and Menu Items for generating views and menu items for dynamic entities.

The example below defines the LoyaltyLevel dynamic entity with several attributes, validation constraints, and a couple of generated views:

- name: "LoyaltyLevel"
  resourceRoles:
    read:
      - "employee"
      - "manager"
    create:
      - "manager"
    update:
      - "manager"
    delete:
      - "manager"
  messages:
    en: "Loyalty level"
    de: "Treuestufe"
  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"
  attributes:
    - name: "name"
      javaClass: "java.lang.String"
      instanceName: true
      messages:
        en: "Name"
    - name: "description"
      javaClass: "java.lang.String"
      lob: true
      messages:
        en: "Description"
    - name: "publicSummary"
      javaClass: "java.lang.String"
      calculated:
        evaluator: "spel"
        expression: "(name ?: '') + ': ' + (description ?: '')"
        dependsOn:
          - "name"
          - "description"
      messages:
        en: "Public summary"
    - name: "discount"
      javaClass: "java.math.BigDecimal"
      validation:
        constraints:
          - annotation: "DecimalMin"
            parameters:
              value: "0"
          - annotation: "DecimalMax"
            parameters:
              value: "100"
      messages:
        en: "Discount"
  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"
        icon: "vaadin:star"
        title:
          en: "Loyalty levels"
        resourceRoles:
          - "employee"
          - "manager"
      descriptor:
        template: "default"
    - type: "detail"
      viewId: "LoyaltyLevel.detail"
      viewTitle:
        en: "Loyalty level"
      descriptor:
        template: "default"
      handlers:
        - event: "initEntity"
          expression: "entity.name = 'New level'"
        - event: "valueChange"
          componentId: "discountField"
          expression: "components.setRequired('descriptionField', event.value != null)"
    - type: "read"
      viewId: "LoyaltyLevel.read"
      viewTitle:
        en: "Loyalty level"

Attributes

Every attribute is one of the following kinds, distinguished by which field it defines: a datatype attribute, a reference attribute, a collection attribute, or an enumeration attribute.

Datatype Attributes

A datatype attribute holds a simple value such as a string, number, date, or boolean. You define it by selecting its type, which is stored as a javaClass. For string and byte-array attributes you can also set a length and mark them as large objects with lob. The taxId attribute shown in Extending Static Entities is a datatype attribute.

For the full list of supported types, see supported types.

Instance Name

Select Instance name for an attribute to use its value as the instance name of the entity. An entity can have only one instance name attribute. If another attribute already has this flag, the attribute dialog shows its name, and selecting the flag moves it to the current attribute. A calculated attribute can also be the instance name.

Reference Attributes

A reference attribute is a single-valued link to another entity. You select the target entity, and at runtime the attribute stores a reference to one instance of it.

- name: "loyaltyLevel"
  entityName: "LoyaltyLevel"
  lookup:
    type: "DROPDOWN"
    actions:
      - "entity_lookup"
      - "entity_clear"
  messages:
    en: "Loyalty level"

Lookup Field

Since Jmix 3.1

For a single-valued reference, you can choose the UI component that generated views use to select the referenced instance. Set it in the Lookup field type and Lookup actions fields of the attribute dialog. The loyaltyLevel attribute in the example above uses a drop-down list.

Lookup field type can have the following values:

  • DROPDOWN – an entityComboBox. Items are loaded while the user types, by the instance name of the referenced entity, so this type works for large tables. If the instance name of the referenced entity is not based on string attributes, the field uses a lookup view instead.

  • VIEW – an entityPicker that opens a lookup view. If no actions are set, the field gets the standard lookup and clear actions.

If the type is not set, the default component is used.

Lookup actions sets the buttons of the field: entity_lookup, entity_open, entity_clear.

These settings work like the @LookupField annotation on a reference attribute of a regular entity.

Collection Attributes

A collection attribute holds an ordered list of child instances (a composition). The target entity must be a dynamic entity. Mark the attribute as a collection in the editor to make a reference hold multiple ordered values:

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

Enumeration Attributes

An enumeration attribute stores one of the values of a dynamic enumeration. You select the enumeration that the attribute refers to:

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

Enumerations

A dynamic enumeration defines a fixed set of named values that can then be used by enumeration attributes. Add an enumeration in the editor, give it a name, and define its values with their stored ids and captions.

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"

All value ids within one enumeration must be of the same kind: either all integer ids (as in the example above) or all string ids.

Calculated Attributes

A calculated attribute is read-only and is computed on access from an expression rather than stored. You write the expression in Spring Expression Language (SpEL) and list the attributes it dependsOn so they are loaded together with it.

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

Because their values are not stored in the database, calculated attributes cannot be used for filtering or sorting at the database level.

Validation

You can attach validation constraints to an attribute to restrict the values it accepts. Each constraint has a type (such as Pattern, Size, or DecimalMax), optional parameters, and an optional message.

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

Entity-level validation is also supported, allowing a constraint to span several attributes of an entity. See YAML Reference for the full list of constraints and for entity-level validation.

Unique Constraints

To require that an attribute’s value is unique across all instances, mark it as unique. This is a shorthand for a single-attribute unique constraint:

unique: true

To require that a combination of several attributes is unique, define a composite unique constraint on the entity:

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

Uniqueness is enforced by database constraints. It is not supported for soft-deletable static entities.

Security

You can restrict access to dynamic entities and attributes using resource roles. Grants are additive — listing a role grants it the corresponding access, and access that is not granted is denied. The referenced roles must already exist in the application; the examples below use illustrative employee and manager roles.

At the entity level, you grant read, create, update, and delete access. This is supported for dynamic entities:

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

At the attribute level, you grant view and modify access:

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

For more about resource roles, see resource roles.

Access to the Model Settings

The add-on provides the following resource roles for the Dynamic model settings view. Assign one of them to users who work with the model.

Role name Code Access

Dynamic model: view settings

dynmod-view-settings

Open the model settings and the model history. The model cannot be changed.

Dynamic model: modify settings

dynmod-modify-settings

Full access. Apply any change, including changes that delete data.

Dynamic model: modify settings without data loss

dynmod-safe-modify-settings

Apply only changes that cannot lose stored data.

Changes Without Data Loss

Since Jmix 3.1

The "Dynamic model: modify settings without data loss" role lets users extend the model without the risk of losing stored data. A user with this role can edit the model in the Visual and Code presentations and apply the following changes: new entities, attributes, enumerations and enumeration values, and changes to validation, views, menu items, messages and resource roles.

The user cannot apply changes that can lose data:

  • removing an applied entity or attribute;

  • renaming an applied entity or attribute in YAML, because a rename is applied as a removal and a creation;

  • removing an applied enumeration;

  • removing a value from an applied enumeration.

In the Visual presentation, applied items cannot be removed. Items added after the last apply can still be removed. If the edited model contains changes that are not allowed, the Dynamic model changes view lists them, and the model cannot be applied until you remove these changes.

The restriction is checked on the server. It cannot be avoided by saving the model settings in another way, for example through the entity inspector.