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

# 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

```java
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

```java
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

```java
@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

```java
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

```java
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()

```java
// 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

```java
        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()

```java
// 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](/qualityone/vault-sdk/entry-points/triggers/role-triggers)  
**Next:** [Actions](/qualityone/vault-sdk/entry-points/actions)