**Source URL:** https://general.veevavault.dev/vault-sdk/entry-points/triggers/role-triggers/anatomy-role-triggers.md

# Anatomy of a Record Role Trigger



You can implement record role 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.

### Line #1: Package {#line-1-package}

```
package com.veeva.vault.custom.triggers.case3;

```

A custom record role 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.

### Lines #3-16: Import {#lines-3-16-import}

```
import com.veeva.vault.sdk.api.core.RollbackException;

```

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.

### Line #18: Annotation {#line-18-annotation}

```
@RecordRoleTriggerInfo(object="product__v", events={RecordRoleEvent.BEFORE, RecordRoleEvent.AFTER},
	order=TriggerOrder.NUMBER_2)

```

The class annotation (`@RecordRoleTriggerInfo`) 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 instance `product__v`. This specifies the object that the trigger code will execute on.

* “event”: can be a single or multiple events, for example,
`{RecordRoleEvent.BEFORE, RecordRoleEvent.AFTER}`. This specifies the Event(s) that the trigger code will execute on.

* “order”: [Optional] the order of a trigger will execute relative to the other triggers on the same object and Event. Lower orders execute first.

### Line #19: Class Name {#line-19-class-name}

```
public class CheckProductRole implements RecordRoleTrigger {

```

The class name declaration must include the `public` modifier and `implements RecordRoleTrigger`. As a best practice, class name should indicate the object affected by this trigger and some functional description, for example, `CheckProductRole implements RecordRoleTrigger` means a trigger on a Product that does validation on Role assignment.

### Line #20: execute() method {#line-20-execute-method}

```
public void execute(RecordRoleTriggerContext rroletc) {
        String ROLE_TO_READ = "owner__v";

```

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

### Line #27: getRecordRoleEvent() {#line-27-getrecordroleevent}

```
// Get Record Role changes
        RecordRoleEvent event = rroletc.getRecordRoleEvent();

```

Get the record role Event from the `RecordRoleTriggerContext`. This trigger executes on both `BEFORE` and `AFTER` events, checking the context allows the code to check in which Event the code is executed.

### Line #28 {#line-28}

```
        List<RecordRoleChange> rrchanges = rroletc.getRecordRoleChanges();

```

The `RecordRoleChanges()` method return a list of RecordRoleChange.
A `recordRoleChange` captures all changes done on the record role:

* Users added in the role

* Users removed from the role

* Groups added in the role

* Groups removed from the role

### Line #37: getRecordRole() {#line-37-getrecordrole}

```
// Get RecordRoleChange details 
            RecordRole rrole = rrchange.getRecordRole();

```

A `recordRoleChange` provides a method `getRecordRole()` returning the current `recordRole` that is being changed. In a `BEFORE` Event, the `recordRole` exposes the role assigned before the change. In an `AFTER` Event, the `recordRole` exposes the role assignments after the change.



---

**Previous:** [Role Triggers](/vault-sdk/entry-points/triggers/role-triggers)  
**Next:** [Actions](/vault-sdk/entry-points/actions)