Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Entities

Entities are the primary data structures in a Mendix domain model. Each entity corresponds to a database table (for persistent entities) or an in-memory object (for non-persistent entities).

Entity Types

TypeMDL KeywordDescription
PersistentPERSISTENTStored in the database with a corresponding table
Non-PersistentNON-PERSISTENTIn-memory only, scoped to the user session
ViewVIEWBased on an OQL query, read-only
ExternalEXTERNALFrom an external data source (OData, etc.)

CREATE ENTITY

[/** <documentation> */]
[@Position(<x>, <y>)]
CREATE [OR MODIFY] <entity-type> ENTITY <Module>.<Name> (
  <attribute-definitions>
)
[INDEX (<column-list>)]
[ON BEFORE|AFTER CREATE|COMMIT|DELETE|ROLLBACK CALL <Module>.<Microflow> [RAISE ERROR]]
[;|/]

Persistent Entity

The most common type. Data is stored in the application database:

/** Customer master data */
@Position(100, 200)
CREATE PERSISTENT ENTITY Sales.Customer (
  /** Auto-incrementing unique identifier */
  CustomerId: AutoNumber NOT NULL UNIQUE DEFAULT 1,
  /** Full legal name of the customer */
  Name: String(200) NOT NULL ERROR 'Name is required',
  /** Primary contact email address */
  Email: String(200) UNIQUE ERROR 'Email must be unique',
  /** Current account balance */
  Balance: Decimal DEFAULT 0,
  /** Whether the account is active */
  IsActive: Boolean DEFAULT TRUE,
  /** Timestamp of account creation */
  CreatedDate: DateTime,
  /** Current lifecycle status */
  Status: Enumeration(Sales.CustomerStatus) DEFAULT 'Active'
)
INDEX (Name)
INDEX (Email);

Non-Persistent Entity

Used for helper objects, filter parameters, and UI state that does not need database storage:

CREATE NON-PERSISTENT ENTITY Sales.CustomerFilter (
  SearchName: String(200),
  MinBalance: Decimal,
  MaxBalance: Decimal
);

View Entity

Defined by an OQL query. View entities are read-only:

CREATE VIEW ENTITY Reports.CustomerSummary (
  CustomerName: String,
  TotalOrders: Integer,
  TotalAmount: Decimal
) AS
  SELECT
    c.Name AS CustomerName,
    COUNT(o.OrderId) AS TotalOrders,
    SUM(o.Amount) AS TotalAmount
  FROM Sales.Customer c
  LEFT JOIN Sales.Order o ON o.Customer = c
  GROUP BY c.Name;

CREATE OR MODIFY

Creates the entity if it does not exist, or updates it if it does. New attributes are added; existing attributes are preserved:

CREATE OR MODIFY PERSISTENT ENTITY Sales.Customer (
  CustomerId: AutoNumber NOT NULL UNIQUE,
  Name: String(200) NOT NULL,
  Email: String(200),
  Phone: String(50)  -- new attribute added on modify
);

System Attributes (Auditing)

Persistent entities can track who created/modified objects and when. Declare them as regular attributes using pseudo-types (like AutoNumber):

CREATE PERSISTENT ENTITY Sales.Order (
  OrderNumber: AutoNumber,
  TotalAmount: Decimal,
  Owner: AutoOwner,
  ChangedBy: AutoChangedBy,
  CreatedDate: AutoCreatedDate,
  ChangedDate: AutoChangedDate
);
Pseudo-TypeSystem AttributeSet When
AutoOwnerSystem.owner (→ System.User)Object created
AutoChangedBySystem.changedBy (→ System.User)Every commit
AutoCreatedDateCreatedDate (DateTime)Object created
AutoChangedDateChangedDate (DateTime)Every commit

Toggle on existing entities with ALTER ENTITY:

ALTER ENTITY Sales.Order ADD ATTRIBUTE Owner: AutoOwner;
ALTER ENTITY Sales.Order DROP ATTRIBUTE ChangedDate;

Annotations

@Position

Controls where the entity appears in the domain model diagram:

@Position(100, 200)
CREATE PERSISTENT ENTITY Sales.Customer ( ... );

Documentation

A /** ... */ comment before the entity or before an individual attribute becomes its documentation in Studio Pro:

/** Customer master data.
 *  Stores both active and inactive customers.
 */
@Position(100, 200)
CREATE PERSISTENT ENTITY Sales.Customer (
  /** Auto-incrementing unique identifier */
  CustomerId: AutoNumber NOT NULL UNIQUE DEFAULT 1,

  /** Full legal name of the customer */
  Name: String(200) NOT NULL ERROR 'Name is required',

  /** Primary contact email address */
  Email: String(200) UNIQUE ERROR 'Email must be unique',

  /** Current account balance in the base currency */
  Balance: Decimal DEFAULT 0,

  /** Whether the customer account is active */
  IsActive: Boolean DEFAULT TRUE,

  /** Timestamp of account creation */
  CreatedDate: DateTime,

  /** Current lifecycle status */
  Status: Enumeration(Sales.CustomerStatus) DEFAULT 'Active'
)
INDEX (Name)
INDEX (Email);

Attribute-level documentation appears in Studio Pro when hovering over the attribute in the domain model.

Entity Event Handlers

Persistent entities can have microflow event handlers that run before or after Create, Commit, Delete, or Rollback operations. The optional RAISE ERROR clause makes the handler act as a validation microflow — if it returns false, the operation is aborted.

CREATE PERSISTENT ENTITY Sales.Order (
  Total: Decimal,
  Status: String(50)
)
ON BEFORE COMMIT CALL Sales.ACT_ValidateOrder RAISE ERROR
ON AFTER CREATE CALL Sales.ACT_InitDefaults;

Event handlers can also be added or removed via ALTER ENTITY:

-- Add a handler to an existing entity
ALTER ENTITY Sales.Order
  ADD EVENT HANDLER ON BEFORE DELETE CALL Sales.ACT_CheckCanDelete RAISE ERROR;

-- Remove a handler
ALTER ENTITY Sales.Order
  DROP EVENT HANDLER ON BEFORE COMMIT;

Moments: BEFORE, AFTER Events: CREATE, COMMIT, DELETE, ROLLBACK

Each (Moment, Event) combination supports one handler per entity. The microflow must exist in the project (validated at execution time).

DROP ENTITY

Removes an entity from the domain model:

DROP ENTITY Sales.Customer;

See Also