Mendix Advanced Developer study materials
Mendix Advanced Developer study resources

Mendix Advanced Developer cheat sheet

Mendix Advanced Developer · Keep the key ideas within reach.

Quick reference

Advanced domain modeling and data structure

  • Entity inheritance is single-table: the general entity and all specializations share one database table, a discriminator column stores the type, and specialization attributes are nullable for rows of other types.

  • A reference association is persisted as a foreign-key column in the owner entity's table; the non-owner side stores nothing, so changing the owner after data exists requires a migration.

  • A reference set (many-to-many) persists as a separate join table, and both sides can be queried from either direction regardless of which side is the owner.

  • Delete behavior is configured per association: delete the object only, delete the object plus its referenced objects (cascade), or delete the object plus the references; cascade is never the default.

  • Every persistent entity implicitly has ID (AutoNumber), CreatedDate, ChangedDate, ChangedBy, and the System.owner association to System.User.

  • Calculated attributes are computed from an expression or microflow, are never persisted, and therefore cannot be used as a constraint in a database XPath retrieve.

  • Non-persistent entities are never stored, cannot be retrieved from the database by XPath, and are the standard type for page parameters, helper objects and client-only data.

  • A 'unique' validation rule creates a real database unique constraint; 'required', range and regex rules are model-level checks applied at commit or explicit validation time.

  • Create a database index for every attribute combination used in XPath WHERE clauses, sorting or entity-access XPath; in a composite index, leading column order determines whether the index can be used.

Quick reference

Security and access control

  • At security level 'Production', every entity needs entity access and every page, microflow and nanoflow needs allowed roles; anything left unconfigured is denied.

  • Module roles are defined inside a single module; user roles are app-wide and are mapped to module roles per module; a user's effective rights are the union of the module roles reached through all their user roles.

  • Entity access rights (create/read/write/delete) are set per attribute and per association; multiple access rules for the same role are OR-ed, and so are their XPath constraints.

  • Access-rule XPath can use [%CurrentUser%], [%CurrentDateTime%] and the System.owner association; the microflow equivalents are $currentUser plus the 'Apply entity access' setting.

  • 'Apply entity access' defaults to true and makes a microflow enforce entity-access XPath and member rights; false skips per-row checks and is only safe for flows whose scope was already validated by the caller.

  • A microflow with no allowed module roles cannot be triggered from a page or client call, but other server-side microflows can still call it.

  • Demo users exist only at 'Prototype/demo' security; anonymous access requires guest access to be enabled plus rights granted to the 'Anonymous' user role.

  • Published REST and OData services authenticate per operation or per service (guest, basic, active session, custom microflow); entity access still applies inside the handler microflows.

  • Passwords are stored as bcrypt hashes under a configurable password policy; SSO is implemented with the SAML or OIDC modules rather than a hand-built login microflow.

Quick reference

Microflow and nanoflow logic, validation and error handling

  • Nanoflows run on the client and support only a subset of activities: no Java actions, no call-microflow activity and no REST or SOAP calls; they can call other nanoflows and JavaScript actions.

  • A microflow executes in one database transaction: Commit persists objects, and an unhandled error rolls back every uncommitted change made in that microflow and in the flows it called.

  • An error event with a custom handler exposes $latestError (System.Error with message and type); the handler can log and continue, or rethrow to propagate the error upward.

  • 'Raise error' throws a message-defined error; the nearest error event on the call stack catches it, and if unhandled it aborts the transaction and shows the message to the user.

  • 'Validation feedback' attaches an error to one attribute of one object; the client renders the message at that field and the flow stops unless an error handler catches it.

  • Loop control: 'Break' exits the loop, 'Continue' jumps to the next iteration, and variables created inside the loop body go out of scope at the end of each iteration.

  • Return values must match the declared return type; an object return may be empty, so the calling flow must test for empty before using the result.

  • A microflow marked 'asynchronous' (Mendix 9.12+) is called fire-and-forget: the caller does not wait, receives no return value, and the flow runs in its own transaction.

Quick reference

Integration: REST, SOAP, OData and mapping

  • 'Call REST' returns a System.HttpResponse: read StatusCode to branch on 2xx/4xx/5xx and Content (a string) as the source for an import mapping.

  • Import-mapping object handling per element is Create, Find (XPath by key), Find or create, or Parameter; 'Find or create' is the rule that prevents duplicate objects on repeated imports.

  • A published REST operation is a resource path plus HTTP method plus handler microflow plus authentication method; generated OpenAPI documentation is served at the /rest-doc/ path of the app.

  • Published OData services expose entity sets with $filter, $expand, $orderby, $top, $skip and $count; each query option must be enabled on the service before clients can use it.

  • Consumed SOAP requires a WSDL; operations are bound to microflows through XML mappings, and a SOAP fault surfaces as a catchable error in the calling microflow.

  • JSON structures and XML schemas are created from a sample message or schema file and then generate the import/export mappings; after a contract change the structure and mapping must be updated manually.

  • An export mapping converts Mendix objects into an XML or JSON string (or a DOM document) that is then placed in the request body of the outgoing REST or web service call.

Quick reference

Performance and scalability tuning

  • XPath constraints are translated into SQL WHERE clauses; retrieving a whole table and filtering per object in a loop (the N+1 pattern) is the most common performance defect.

  • Composite index rule: an index serves constraints on its leading column, or on its leading columns in order; a query that starts at the second column cannot use it.

  • Use limit and offset on Retrieve for paged lists, and an aggregate 'count' instead of retrieving a list and calling length on it.

  • Every commit is a database round-trip that holds locks; commit once at the end of a flow rather than inside each loop iteration.

  • Non-persistent entities and 'Retrieve by association' avoid extra queries compared with repeated XPath retrieves for the same data.

  • Task queue (Mendix 9.12+) and scheduled events move heavy work out of the user's request; concurrency is bounded by configuration, not by the number of users.

  • Any runtime state that must survive horizontal scaling belongs in the database; node-local memory breaks as soon as a second runtime instance is added.

Quick reference

Application architecture and reusable module design

  • Export Module produces an .mpk file; Import Module adds the module's domain model, logic, pages and module roles, and the consumer must still map those module roles to its own user roles.

  • Dependencies point one way: if module A references module B, B must never reference A, otherwise neither can be exported or reused cleanly.

  • A module's public surface is exactly the microflows and entities that can be reached through allowed module roles; everything else is internal and may change between versions.

  • Mendix has no visibility modifier, so naming conventions and a 'Private_' prefix are the mechanism that documents which parts form the internal API.

  • Shared configuration belongs in constants with per-environment overrides, not in hard-coded values or model edits per environment.

  • Cross-module navigation to pages breaks reuse; the owning module should expose a microflow or page that the consuming module calls instead.

  • A module that depends on a specific layout, theme class or app-level user role cannot be reused in another app without being edited.

Quick reference

Deployment, environments and operations

  • One deployment package (.mda) is built and transported to acceptance and production; per-environment differences come from constants, log levels and custom runtime settings.

  • Scheduled events run on only one node of a cluster (leader election), while 'after startup' microflows run on every node and therefore must be idempotent.

  • Log output is filtered per environment by node name and level; the first argument of the Log activity is that node name, usually the module name.

  • Mendix Cloud makes automatic backups; restoring one requires the environment to be stopped and returns the environment to the state captured in that backup.

  • Scaling options are more runtime instances (horizontal) and more memory per instance (vertical); database load is reduced through indexes and query changes, not by scaling the runtime.

  • The runtime's Java version must match what the deployment package was built for; a mismatch fails at startup rather than at build time.

  • Custom runtime settings (connection pool size, session timeout and similar) are applied per environment in the portal and take effect without rebuilding the package.

Quick reference

Java actions and runtime extensibility

  • Java action shape (Mendix 9+): the class extends CustomJavaAction, the constructor takes IContext plus the declared parameters, and executeAction() returns T.

  • Object creation: Core.create(context, Entity.entityName), then the generated proxy class in .proxies for setters; Core.commit(context, obj) persists the object.

  • Retrieval calls Core.retrieveXPathQuery, Core.retrieveId and Core.retrieveByPath; a valid IContext makes entity access and the caller's transaction apply.

  • Throwing an exception from executeAction() surfaces as a runtime error that the calling microflow can catch with an error event; unhandled, it rolls back the transaction.

  • Logging uses Core.getLogger("ModuleName") with debug, info, warn or error; the output obeys the environment's log levels for that node.

  • Proxy classes are generated from the domain model; after an entity or attribute rename, stale proxies break compilation and must be regenerated.

  • Java actions cannot be called from nanoflows; client-side custom logic must be written as a JavaScript action instead.

  • Third-party JARs are placed in the project's userlib folder and are packaged into the .mda, so they must also be present when the package is built.