Skip to content

Anatomy of a Record Trigger

You can implement record triggers as normal Java classes. You can express complex business logic within a trigger class.

The code sample below explains the anatomy of a typical, basic trigger class. This example simply defaults a field value based on another field when creating a new record.

Anatomy of a Vault Java SDK Record Trigger.Anatomy of a Vault Java SDK Record Trigger.

The explanations and line numbers below refer to the code sample above.

A custom record trigger must be under the com.veeva.vault.custom package. You can have further sub-package names as you see fit to organize your triggers. For example, you might use com.veeva.vault.custom.rim.submissions.triggers to indicate custom triggers for a RIM Submissions project.

Only references to Vault Java SDK (com.veeva.vault.sdk.api.*) and a limited number of allowlisted classes, interfaces, and methods in the JDK are allowed. For example, String, LocalDate, List, etc.

The class annotation (@RecordTriggerInfo) indicates that this class is a record trigger. The annotation specifies the Object, event(s), and Order of execution.

  • "object": Must be a valid object name. For example, product__v. This specifies the object that the trigger code will execute on.
  • "event": Can be a single event or multiple events, for example, {RecordEvent.BEFORE_INSERT, RecordEvent.BEFORE_UPDATE}. This specifies the event(s) that the trigger code will execute on.
  • "order": [Optional] the order a trigger will execute relative to other triggers on the same object and event. Lower orders execute first.

The class name declaration must include the public modifier and implements RecordTrigger. As a best practice, class name should indicate the object affected by this trigger and some functional description, for example, ProductFieldDefaults implements RecordTrigger means a trigger on Product that defaults some field values.

You must implement this method for the RecordTrigger interface. This method has an instance of RecordTriggerContext passed in, so you can interact with the record(s) on which a user has initiated some operation.

When a user performs a record operation whether by UI or API, such as creating a new record, the record being created is the context record. The operation may have multiple context records such as in a Bulk Create.

A list of records affected by the operation can be retrieved from RecordTriggerContext#getRecordChanges, and you can loop through each record to get field values and/or set field values. Your business logic is enclosed in this loop.

Line #21: getValue(String fieldName, ValueType.<T> fieldType)

Section link for Line #21: getValue(String fieldName, ValueType.&lt;T&gt; fieldType)

You can retrieve field values from the context record. Trigger code operates as the System user, so no record level or field level security apply. All records and fields are accessible.

For new records, only new values are available. For updating records, both old and new values are available. The fieldName argument must be a valid field name in the object. For example, name__v. The fieldType argument must match the Vault field type in order to return the appropriate Java data type. Use the Data Type Map to find out how data types are mapped to objects in Vault.

Line #22: setValue(String fieldName, Object fieldValue)

Section link for Line #22: setValue(String fieldName, Object fieldValue)

You can set field value on fields that are editable. System fields, such as created_by__v and state__v, and Lookup fields are not editable.

The fieldName argument must be a valid field name in the object. The fieldValue argument must be an object of the appropriate data type for the field in the fieldName argument. Use the Data Type Map to find out how data types are mapped to objects in Vault.

The Vaut Java SDK supports record triggers on the user__sys object. Users triggers work the same way as other record triggers, with some exceptions.

Most record triggers execute whenever a data operation makes changes to an object record. Unlike most record triggers, user triggers execute only when changes are made directly to the user__sys object record in a Vault. In other words, user triggers are not invoked by indirect updates.

For example, triggers on the user__sys object are not invoked in the following scenarios:

  • Synchronizing user attributes across multiple domains, for example, updates to domain user attributes like first name, last name, or email address only invoke user triggers in the Vault where the change originated. This also applies to cross-domain users.
  • Updating the domain user Status attribute to Inactive
  • Creating or updating System-owned users