4D Blog

Home Product ORDA – Handle an event-driven logic during database operations

ORDA – Handle an event-driven logic during database operations

November 28, 2025

Product

This feature keeps going on with a new paradigm: handle data in an event-driven way. The 4D 21 provides a complete series of events related to database operations (save or drop).

ORDA events can replace triggers and offer many more advantages: more control, allowing you to code your business logic (including time consuming jobs such as printing invoices or storing external data) directly in an ORDA data class function. They respond to events on data level such as new, modify, save, drop (CRUD)

ORDA events offer precise granularity and sophisticated error handling, leading to a strong data integrity and a better code organisation.

Discover how to implement the appropriate business logic in each step of a save or drop action.

HDI_ORDA_Events_Save_Drop

ORDA events – A waltz in several times

In this previous blogpost, we unveiled the first event out of a long series: the touched event.

The new database operation events are designed to be used in the ORDA layer through entities handled with the This keyword which is not possible with triggers.

Compared to triggers, those events offer finer granularity for detecting specific database operations steps and sophisticated error handling that can stop the action if needed.

Unlike triggers, events not only allow you to implement actions before the save/drop actions. They can also run actions during and after the save/drop operations. 

The error handling is powerful, you can return customized errors with different severities and detailed extra information for the end user. 

Previously, you could implement some functions for this, but you had to call them manually everywhere it was necessary.

Now, this feature offers a complete event-driven logic, automatically triggered at the appropriate time. Implement it once and let the 4D engine handle it at run time:

  • Inconsistent data can be rejected beforehand without involving the persistence layer
  • Interactions with external systems can happen precisely when the 4D data is persisted
  • Actions can be triggered when the save/drop fails

 

And good news, in opposite to triggers, ORDA does not lock the entire underlying table of a dataclass while saving / dropping a entities. Several events can run in parallel as long as they involve distinct entities (i.e. records). 

If you rely on a full lock of the entire table to handle unique sequence numbers or similar, you have to handle it on your own, for example with singletons – and this allows you to lock only when needed – and have full control about this process.

The distinct phases of a database operation

When a save or drop action runs, these events allow you to implement business logic in three distinct phases of the action:

  • Validating the save or drop action: Useful for checking data consistency regarding this action, e.g.:
    • Is the status of the entity about to be dropped set to “TO DELETE” ?
    • Is the departure date < arrival date in a booking entity ?

Thanks to this event, you can stop the save/drop action and return an error to the end user. This ensures the data will be consistent and ready before entering the save/drop action itself.

  • During saving / dropping: Use this if you need to synchronize your database operations with an external system, e.g.:
    • When saving an entity, write data on a disk, create a document on a Google Drive, etc.

In this event, you can return errors in case of failure to stop the action. These errors can then be handled in the after event described below.

  • After the save or drop action: Here you can take measures regarding potential errors raised during the save/drop actions, e.g.:
    • Mark a product as “To be checked” because an error occurred during the drop action

 

Thanks to these events, each step of the save or drop action can have its own dedicated business logic.

These events are triggered as soon as the database operation is triggered using ORDA or the REST server.

Watch the video below. It goes through the provided HDI with more details.

 

let’s see this in action with examples

where to implement events

ORDA events must be implemented in the Entity class using the event keyword.

the validate events

These events are triggered before the save or drop action and can stop the action by returning an error.  In this case, the other events described below (except the after event) are not triggered.

They can be implemented:

  • At the attribute level: to check a specific attribute’s consistency
  • At the entity level: to check the entity content globally or compare attributes

 

Example:

In this example, in the ProductsEntity class, a validateSave event has been implemented for the margin attribute. The user can’t save a product with a margin lower than 50%. In this case, an error is returned to stop the save action and give feedback to the end user. 

// ProductsEntity class
//
// validateSave event at attribute level
Function event validateSave margin($event : Object) : Object
	
var $result : Object
	
//The user can't create a product whose margin is < 50%
If (This.margin<50)
	$result:={errCode: 1; message: "The validation of this product failed"; \
	extraDescription: {info: "The margin of this product ("+String(This.margin)+") is lower than 50%"}; seriousError: False}
End if 
return $result

The same logic applies for a validateDrop event. For example, you can prevent a user from dropping a product whose status is not “To delete”.

the saving / dropping events

These events are triggered precisely during the save or drop action and can return errors if something goes wrong. They can be implemented:

  • At the attribute level: to monitor changes to specific attribute values
  • At the entity level: to check the entity content globally or compare attributes

 

Example:

In this example, in the ProductsEntity class, a saving event has been implemented for the userManualPath attribute. When a product is saved, the user manual document is created on the disk and its path is stored in the userManualPath attribute. Those two actions must be consistent.

If there is an error while creating the user manual document on the disk, an error is returned to give feedback and to be proceeded in the next event (afterSave) detailed below.

Note the content of the file is generated previously outside the saving event because it can be time consuming.

// ProductsEntity class
// saving event at attribute level
Function event saving userManualPath($event : Object) : Object
	
var $result : Object
var $userManualFile : 4D.File
var $fileCreated : Boolean
	
If (This.userManualPath#"")
	$userManualFile:=File(This.userManualPath)
				
	// The user manual document file is created on the disk
	// This may fail if no more space is available
	Try
            // The content of the file has been generated and stored in a map in Storage.docMap previously
	    $docInfo:=Storage.docMap.query("name = :1"; This.name).first()
            $userManualFile.setContent($docInfo.content)
	Catch
		// E.g.: No more space on disk
		$result:={errCode: 1; message: "Error during the save action for this product"; extraDescription: {info: "There is no available space on disk to store the user manual"}}
	End try
End if 
	
return $result

The same logic applies for a dropping event. For example, you can drop the user manual document while dropping the product.

the after events

These events are triggered after the Save or Drop action. Because the action is finished, they can’t return errors. Their main purpose is to trigger business logic if a failure occurred during earlier events.

If no error occurred, they can also handle post-success logic — for example, sending a confirmation email.

These events are implemented at entity level only.

Example:

In this example, in the ProductsEntity class, an afterSave event has been implemented. If the userManualPath attribute has not been properly saved previously, its value is reseted to be consistent with the missing user manual document on the disk.

// ProductsEntity class
Function event afterSave($event : Object)
	
	If (($event.status.success=False) && ($event.status.errors=Null))  // $event.status.errors is filled if the error comes from the validateSave event
		
		// The userManualPath attribute has not been properly saved
		// Its value is reset
		If ($event.savedAttributes.indexOf("userManualPath")=-1)
			This.userManualPath:=""
			This.status:="KO"
		End if 
		
	End if 

The same logic applies for an afterDrop event— e.g., when dropping a product fails, you can log the incident.

Note long operations must be avoided as far as possible in events. If possible, such operations must be implemented elsewhere.

Do not wait to implement events to rely on a strong data integrity. 

👉 Download the HDI to dive into the implementation details of ORDA events and watch the video below to have more details about running the HDI.

Add the EN video link

 

Discuss

Tags 21, Event on data, ORDA, ORDA Data model classes

Latest related posts

  • December 3, 2025

    Give AI to a 30 years old 4D application

  • November 27, 2025

    ORDA – Permissions – Restrict / allow web access to the resources in one click

  • November 17, 2025

    Goodbye 4D Internet Commands – Hello Modern Internet Integration

Avatar
Marie-Sophie Landrieu-Yvert
- Product Owner - Marie-Sophie Landrieu-Yvert joined the 4D Product team as a Product Owner in 2017. In this role, she is responsible for writing user stories and translating them into functional specifications. She also ensures that the delivered feature implementation meets the customer's needs. Marie-Sophie graduated from the engineering school ESIGELEC and began her career as an engineer at IBM in 1995. She took part in various projects (maintenance and development projects) and worked as a COBOL developer. She then moved on to work as a UML designer and Java developer. More recently, her main responsibilities included analyzing and writing functional requirements, and coordinating business and development teams.
  • Deutsch
  • Français
  • English
  • Português
  • Čeština
  • Español
  • Italiano
  • 日本語

Categories

Browse categories

  • AI
  • 4D View Pro
  • 4D Write Pro
  • 4D for Mobile
  • Email
  • Development Mode
  • 4D Language
  • ORDA
  • User Interface / GUI
  • Qodly Studio
  • Server
  • Maintenance
  • Deployment
  • 4D Tutorials
  • Generic
  • 4D Summit sessions and other online videos

Tags

4D-Analyzer 4D AIKit 4D for Android 4D for iOS 4D NetKit 4D Qodly Pro 4D View Pro 4D Write Pro 20 R10 21 Administration AI Artificial Intelligence Build application Class Client/Server Code editor Collections Formula Listbox Logs Mail Microsoft 365 Network Objects OpenAI ORDA PDF Pictures Preemptive Programming REST Scalability Security Session Source control Speed Spreadsheet Tutorial UI User Experience v20 vscode Web Word processor

Tags

4D-Analyzer 4D AIKit 4D for Android 4D for iOS 4D NetKit 4D Qodly Pro 4D View Pro 4D Write Pro 20 R10 21 Administration AI Artificial Intelligence Build application Class Client/Server Code editor Collections Formula Listbox Logs Mail Microsoft 365 Network Objects OpenAI ORDA PDF Pictures Preemptive Programming REST Scalability Security Session Source control Speed Spreadsheet Tutorial UI User Experience v20 vscode Web Word processor
Subscribe to 4D Newsletter

© 2025 4D SAS - All rights reserved
Terms & Conditions | Legal Notices | Data Policy | Cookie Policy | Contact us | Write for us


Subscribe to 4D Newsletter

* Your privacy is very important to us. Please click here to view our Policy

Contact us

Got a question, suggestion or just want to get in touch with the 4D bloggers? Drop us a line!

* Your privacy is very important to us. Please click here to view our Policy