MDL Entity Syntax Reference

SkillAI & models

Gives your agent a syntax reference for Mendix domain model entities, attributes and associations so spellings are exact.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the MDL Entity Syntax Reference skill

About this capability

Complete syntax reference for entities, attributes and associations, every entity kind, attribute type, and association form. Use when writing or altering a domain model and the exact spelling matters.

What this skill tells your AI

The instructions your AI receives, as published by mendixlabs/mxcli in .claude/skills/mendix/mdl-entities/SKILL.md and read by ahel’s review.

Complete syntax reference for creating entities, attributes, and associations.

Entity Types

TypeKeywordStored in DBUse Case
Persistentcreate persistent entityYesBusiness data
Non-Persistentcreate non-persistent entityNoTemporary/view data
Viewcreate view entityNo (OQL query)Aggregated/computed data

Persistent Entity

/**
 * Customer entity for storing customer data
 */
create persistent entity Module.Customer (
  -- String attributes
  Name: string(100) not null,
  Email: string(200),
  Code: string(20) unique,

  -- Numeric attributes
  Age: integer,
  CreditLimit: decimal,

  -- Boolean
  IsActive: boolean default true,

  -- Date/Time
  BirthDate: date,
  -- Use autocreateddate (not datetime) to record when the object was created.
  -- 'CreatedDate' as a plain datetime triggers lint error MDL020.
  CreatedDate: autocreateddate,

  -- Enumeration
  status: Module.CustomerStatus default Active,

  -- Auto-number (REQUIRES a seed via `default N` — without it the build fails
  -- CE7247 "Value cannot be empty")
  CustomerNumber: autonumber default 1
);
/

Non-Persistent Entity

Used for temporary data, form parameters, or calculated values.

/**
 * Search parameters for customer search form
 */
create non-persistent entity Module.CustomerSearchParams (
  SearchName: string(100),
  SearchEmail: string(200),
  MinCreditLimit: decimal,
  IncludeInactive: boolean default false
);
/

Attribute Types

TypeSyntaxExample
StringName: string(length)Name: string(100)
IntegerName: integercount: integer
LongName: longBigNumber: long
DecimalName: decimalAmount: decimal
BooleanName: booleanIsActive: boolean
DateTimeName: datetimeCreatedAt: datetime
DateName: dateBirthDate: date
EnumerationName: Module.EnumNamestatus: Module.Status
AutoNumberName: autonumber default 1Code: autonumber default 1 (seed required)
BinaryName: binaryFileData: binary
Hashed StringName: hashedstringpassword: hashedstring

Attribute Modifiers

ModifierMeaningExample
not nullRequired fieldName: string(100) not null
uniqueUnique constraintCode: string(20) unique
default valueDefault valueIsActive: boolean default true

Note: Boolean attributes auto-default to false when no default is specified.

Generalization (Inheritance)

CRITICAL: EXTENDS goes BEFORE the opening parenthesis, not after!

/**
 * Base entity
 */
create persistent entity Module.Person (
  PersonName: string(100) not null,
  Email: string(200)
);
/

/**
 * Customer extends Person - EXTENDS before (
 */
create persistent entity Module.Customer extends Module.Person (
  CustomerCode: string(20),
  CreditLimit: decimal
);
/

Common parent entities for file/image storage:

-- Image entity (inherits Name, Size, Contents, thumbnail)
create persistent entity Module.ProductPhoto extends System.Image (
  PhotoCaption: string(200),
  SortOrder: integer default 0
);

-- File document (inherits Name, Size, Contents)
create persistent entity Module.Attachment extends System.FileDocument (
  AttachmentDescription: string(500)
);

Wrong (parse error):

-- EXTENDS after ) = parse error!
create persistent entity Module.Photo (
  PhotoCaption: string(200)
) extends System.Image;

Associations

Reference (Many-to-One)

/**
 * Order belongs to one Customer
 */
create association Module.Order_Customer
from Module.Order to Module.Customer
type reference;
/

Direction: from the entity that holds the foreign key (the "many" / child side) to the entity being referenced (the "one" / parent side). Name convention is Child_Parent.

Reference Set (Many-to-Many)

/**
 * Product can be in many Categories
 * Category can have many Products
 */
create association Module.Product_Category
from Module.Product to Module.Category
type reference_set
owner both;
/

Association with Delete Behavior

/**
 * Delete orders when their customer is deleted
 */
create association Module.Order_Customer
from Module.Order to Module.Customer
type reference
delete_behavior DELETE_AND_REFERENCES;
/

Delete behaviors (applied to the referenced to entity):

  • delete_behavior DELETE_AND_REFERENCES - delete the referencing objects too (cascade)
  • delete_behavior DELETE_BUT_KEEP_REFERENCES - delete, nullify the reference (default)
  • delete_behavior DELETE_IF_NO_REFERENCES - only delete when nothing references it

Enumerations

/**
 * Order status values
 */
create enumeration Module.OrderStatus (
  Draft 'Draft',
  Pending 'Pending',
  Approved 'Approved',
  Shipped 'Shipped',
  Delivered 'Delivered',
  Cancelled 'Cancelled'
);
/

View Entity (OQL)

/**
 * Monthly sales summary by customer
 */
create view entity Module.CustomerSalesSummary (
  CustomerName: string(100),
  TotalOrders: integer,
  TotalAmount: decimal,
  LastOrderDate: datetime
)
as
  select
    c.Name as CustomerName,
    count(o.OrderID) as TotalOrders,
    sum(o.Amount) as TotalAmount,
    max(o.OrderDate) as LastOrderDate
  from Module.Customer c
  left join c/Module.Order_Customer/Module.Order o
  GROUP by c.Name;
/

Derived string columns must be string(200). A plain pass-through column (c.Name as CustomerName) inherits its source attribute's length, so declaring string(100) above is fine. But a derived string column — cast(x as string), a string-returning CASE, or a string expression — is normalized by Mendix to the platform default length string(200). Declaring any other length (string(30), unlimited, …) passes mxcli check's parser but fails the MxBuild consistency check with CE6770 "View Entity is out of sync with the OQL Query." mxcli check catches this pre-build as MDL031 with a suggested fix:

create view entity Module.TicketLabel (
  StatusLabel: string(200)          -- derived → must be 200, not string(30)
) as
  select cast(t.Status as string) as StatusLabel from Module.Ticket t;
/

Entity with Index

/**
 * Product with search index
 */
create persistent entity Module.Product (
  Code: string(20) not null,
  Name: string(100) not null,
  Category: string(50),
  Price: decimal
)
index idx_product_code (Code)
index idx_product_category (Category);
/

The on keyword is optional and reads SQL-like: index idx_product_code on (Code) is equivalent to index idx_product_code (Code). Multi-column indexes list the columns in order: index idx_pos on (Row, Col).

Complete Domain Model Example

-- Enumeration
create enumeration Shop.OrderStatus (
  Draft 'Draft',
  Confirmed 'Confirmed',
  Shipped 'Shipped',
  Delivered 'Delivered'
);
/

-- Customer entity
create persistent entity Shop.Customer (
  Name: string(100) not null,
  Email: string(200) not null unique,
  Phone: string(20),
  IsActive: boolean default true,
  CreatedDate: autocreateddate
);
/

-- Product entity
create persistent entity Shop.Product (
  Code: string(20) not null unique,
  Name: string(100) not null,
  description: string(500),
  Price: decimal not null,
  Stock: integer default 0,
  IsAvailable: boolean default true
);
/

-- Order entity
create persistent entity Shop.Order (
  OrderNumber: autonumber default 1,
  OrderDate: datetime not null,
  status: Shop.OrderStatus default Draft,
  TotalAmount: decimal,
  Notes: string(500)
);
/

-- Order line entity
create persistent entity Shop.OrderLine (
  Quantity: integer not null,
  UnitPrice: decimal not null,
  LineTotal: decimal
);
/

-- Associations
create association Shop.Order_Customer
from Shop.Order to Shop.Customer
type reference;
/

create association Shop.OrderLine_Order
from Shop.OrderLine to Shop.Order
type reference
delete_behavior DELETE_AND_REFERENCES;
/

create association Shop.OrderLine_Product
from Shop.OrderLine to Shop.Product
type reference;
/

Quick Reference

Entity Creation

create persistent entity Module.Name (attributes);
create non-persistent entity Module.Name (attributes);
create view entity Module.Name (attributes) as select ...;

Attribute Syntax

attributename: type [(length)] [not null] [unique] [default value]

Association Syntax

create association Module.Child_Parent
from Module.ChildEntity to Module.ParentEntity
[type reference | reference_set]
[owner default | both]
[storage column | table]
[delete_behavior DELETE_AND_REFERENCES | DELETE_BUT_KEEP_REFERENCES | DELETE_IF_NO_REFERENCES];

Enumeration Syntax

create enumeration Module.Name (
  Value1 'Caption1',
  Value2 'Caption2'
);

-- Optionally place the enumeration in a module folder:
create enumeration Module.Currency (
  USD 'US Dollar',
  EUR 'Euro'
) FOLDER 'Shared';
-- Or move an existing one:  move enumeration Module.Currency to folder 'Shared';

Signals

GitHub stars
122
Forks
49
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
mdl-entities
Source
github.com/mendixlabs/mxcli