Class TableTrigger

java.lang.Object
com.orchestranetworks.schema.trigger.TableTrigger
Direct Known Subclasses:
BuiltInTrigger_launchWorkflow

public abstract class TableTrigger extends Object
Specifies methods that are automatically executed when certain operations are performed on a table. This is the EBX® equivalent of database triggers.

Definition in the data model

The trigger must be declared under the element xs:annotation/xs:appinfo:

 <osd:trigger class="com.foo.MyTableTrigger" />
 
where com.foo.MyTableTrigger is the fully qualified name of the class implementing this interface. It is also possible to set additional JavaBean properties:
 <osd:trigger class="com.foo.MyTableTrigger">
         <param1>...</param1>
         <param2>...</param2>
 </osd:trigger>
 
where param1 and param2 are JavaBean properties of the specified class.

For more information, see the JavaBean specification.

Life cycle

  1. When the data model is loaded:
    • the specified class is instantiated through its default constructor and the JavaBean property setters are called (in the example above, setParam1(...) and setParam2(...));
    • the method setup(TriggerSetupContext) is called on the new instance.
  2. During the operational phase: the methods handle... are called every time the associated operation is executed.

If several operations are defined for the same table, they are not executed in any particular order.

Restrictions

Table triggers are not invoked in the following contexts:

Transaction Management

When a record operation is performed, the sequence is the following:

  1. the method handleBefore<Operation> is invoked,
  2. the core record operation is performed (Create, Modify or Delete),
  3. the method handleAfter<Operation> is invoked.

Each trigger method can impact any system, persistent or not, including the EBX® repository. The main cases are outlined below:

  1. the trigger modifies the same dataspace, in which case it must be performed in the same transaction and use the same ProcedureContext.
  2. the trigger modifies another dataspace in the same EBX® repository, in which case it must be performed in another Procedure.
  3. the trigger modifies an external system, for example a registry in the Java memory, an RDBMS or a file system.

CAUTION: in the latter two cases, the system integrity cannot be fully ensured in various cases, for example a sudden server shutdown. Consequently, the system must be carefully designed so as to support such degraded situations. At least, for cases where a Java exception has been thrown during the transaction, the method handleBeforeTransactionCancel(BeforeTransactionCancelContext) can be implemented to rollback the modifications done in the other dataspace or in the other system.

During a single transaction (the first case described above), it is possible to perform a sequence of nested updates. In the following example, table1 has an afterModify trigger which performs a record creation in table2:

  • Start: Modify a record of table1
    • handleBeforeModify in table1
    • Core record modification in table1
    • handleAfterModify in table1
      • Start: Create record in table2
        • handleBeforeCreate in table2
        • Core record creation in table2
        • handleAfterCreate in table2
      • End: Create record in table2
  • End: Modify a record of table1

Known Limitation: A "before trigger" only allows updating the current record content (no access to ProcedureContext is provided). If, at this point, more advanced updates are necessary, a specific service should be used instead of triggers.

Functional guard and exceptions

In the context of a method handleBefore..., it is possible to implement a guard by throwing an OperationException if some functional conditions on the data are not satisfied. This will cancel the current transaction.

Throwing an OperationException instead of a RuntimeException provides the end-user with the benefit of a well-localizable and a more user-friendly error message, when the error happens in the context of the user interface (in contrast, this behavior does not apply to handleBeforeTransactionCancel). In all cases, the current transaction is aborted.

Note: In further detail, if a ProcedureContext raises an exception, any preceding updates made on the repository during nested update executions are first cancelled before the corresponding update method catches the exception. This additional feature is for ensuring that the repository and cache remain consistent, even if the corresponding update method catches the exception.

See Also: