Entity
This section covers runtime configuration options that affect how the ADITO server behaves during execution. Proper tuning of these parameters ensures your application runs reliably and efficiently in production environments.
RecordContainer Cacheβ
Use a dedicated RecordContainerCache
for each RecordContainer
to improve response time for repeated queries.
Each cache must be configured individually. This approach minimizes database access and speeds up data retrieval for frequently requested entities.
π For implementation guidance, refer to the Customizing Manual, appendix "RecordContainerCache".
Image Guidelinesβ
Large images can negatively impact performance, especially when rendering complex datasets in the UI. To maintain fast load times and responsive behavior, follow these image constraints:
-
ContainerComponents (e.g., Table, Timeline, Treetable, GenericMultiple):
- Maximum resolution: 300Γ200 pixels
- Maximum file size: < 10 KB
-
Other ViewTemplates (e.g., detailed views, dashboards):
- Maximum resolution: 4000Γ4000 pixels
- Maximum file size: < 1 MB
Use modern, compressed formats like WebP or JPEG to reduce file size. Avoid unnecessary high-resolution images for thumbnails or icons.
Filtering Behaviorβ
This section applies exclusively to JDitoRecordContainer
. When using a DBRecordContainer
, filtering is handled automatically.
Client-Side Filteringβ
Use client-side filtering when:
- The dataset is small
- Low latency is critical
- Users benefit from fast, incremental search
In this approach, all records are loaded into the client memory and filtered locally.
Advantages:
- Very fast filtering after initial load
- Ideal for small, static datasets
Server-Side Filteringβ
Use server-side filtering when:
- The dataset is large or dynamic
- You need to avoid loading unnecessary data
In this case, each change to the filter term triggers a new query to the database.
Disadvantages:
- Higher load on the database
- Increased latency per filter change
- Issues may arise when filtering translated values
Configurationβ
Filtering in JDitoRecordContainer
is determined by the following properties:
isRequireContainerFiltering
isPageable
If either is set to true
, filtering occurs on the server.
If both are false
, filtering occurs on the client.
Use server-side filtering for large datasets and client-side filtering for small datasets to optimize performance and user experience.
Refreshing Behaviorβ
The ADITO platform supports automatic data refreshes, but these rely on correctly configured dependencies such as the Entityβs siblings
property or Consumer/Provider relationships.
Avoid Unnecessary Refreshesβ
Calling neon.refreshAll
should generally be avoided. It triggers all dependent processes across all EntityFields, which:
- Increases server load
- Introduces latency
- May execute irrelevant logic
Instead, use implicit and targeted refresh mechanisms like:
siblings
property- Consumer/Provider links
- Dependency-aware variables such as:
vars.get("$field.MyConsumerName.insertedRows")
These mechanisms ensure efficient refresh behavior without globally reprocessing unrelated logic.
Asynchronous Methodsβ
Avoid combining asynchronous methods like neon.refreshAll
and neon.setFieldValue
in the same process (e.g., afterSave
, onValueChange
). Doing so can cause deadlocks due to uncontrolled execution timing.
Use them only in safe, isolated contexts such as onActionProcess
.
Refresh from Pending Recordsβ
ADITO supports auto-refresh behavior based on interaction with unsaved changes. You can reference pending records via:
insertedRows
changedRows
deletedRows
By referencing these variables, you establish a dependency that triggers an automatic refresh only when changes are detected β improving both accuracy and performance.
Figure: Example of refresh triggered via consumer dependency
Access Rights (Permissions)β
ADITO provides a modern, client-based access control system, configured primarily through the User Administration > Contexts section in the Global Menu. This approach allows most permission logic to be managed without writing code.
For advanced or sensitive scenarios, however, programmable permissions are still supported β and may be the preferred solution when role-based configuration is insufficient or too limited.
Processing Grantsβ
Use the grantCreate
, grantUpdate
, and grantDelete
properties only when client-based role permissions are insufficient or too complex.
Avoid these programmable grants when the same logic can be configured via the client UI β the client-based model is more maintainable and optimized for common use cases.
Use programmable grants only if:
- The rule applies universally and is not role-specific
- The logic must enforce strict confidentiality and should not rely solely on client configuration
- The condition is complex (e.g., based on logic not representable as a simple attribute)
Example: Only certain employees are allowed to delete already sent documents.
- Create a role named
DELETE_SENT_DOCUMENT
- Assign this role to the permitted users
- In the
grantDelete
logic, check both conditions:
if (document.isSent() && tools.currentUserHasRole("DELETE_SENT_DOCUMENT")) {
return true;
}
Client-Based Permissionsβ
Client-side permissions should be your primary mechanism for managing access rights.
Best practices:
- Avoid defining
update
ordelete
permissions ifread
already restricts access - Keep permission logic minimal and as simple as possible
Incorrect: Redundant logic
- Setting the same complex filters for
read
,update
, anddelete
- The server evaluates all three separately, causing unnecessary overhead
Correct: Single responsibility
- Define strict
read
access - Let
update
anddelete
follow automatically β the user can't modify what they can't see
If separate update
or delete
rules are necessary, restrict them to only whatβs visible after read
filters. Avoid duplicating logic across permission levels.
Conclusionβ
Use Case | Recommended Approach |
---|---|
Standard role-based access control | Client-based permissions |
Logic based on roles and attributes | Client-based (if simple) |
Complex logic or strict confidentiality | grantXXX properties |
Global logic, not user-specific | grantXXX properties |
List Ordering with LexoRankβ
For sortable TreeTables that support drag-and-drop reordering, use LexoRank instead of numeric sort fields.
LexoRank generates sortable string values that make it easy to insert new records between existing ones without requiring full re-sorting. This reduces complexity and improves performance, especially in large tables.
Benefits of LexoRank:
- Efficient reordering without reshuffling all rows
- Better performance in UI components with frequent sorting
- Simplified logic for inserts and updates
π For implementation guidance, refer to the Customizing Manual β Appendix "LexoRank".