Broadleaf Microservices
  • v1.0.0-latest-prod

MutationNotifyEvent

Broadleaf’s DataTracking library provides a JVM-local event system to hook into the persistence lifecycle of Trackable entities. The primary event for this is the MutationNotifyEvent.

Overview

MutationNotifyEvent is a Spring ApplicationEvent published by CrudEntityHelper immediately after an entity has been successfully persisted (created, updated, or deleted) in the database.

This event is particularly useful for triggering side effects that should occur after a change is finalized but don’t require modifying the entity itself. Because it is a local Spring event, it is synchronous by default, allowing you to participate in the same execution flow as the mutation.

Use Cases

Common scenarios for listening to MutationNotifyEvent include:

  • Cache Invalidation: Notifying other components or services to clear their local caches for the modified entity.

  • Audit Logging: Capturing change details to create a formal audit trail.

  • Search Indexing: Triggering a re-index of the modified entity in a search engine like Solr or Elasticsearch.

  • Data Feed Notifications: Informing external systems of data changes via an incremental data feed.

  • Third-Party Integrations: Sending notifications to external APIs (e.g., updating an ERP or CRM) when a record is changed.

Event Structure

The MutationNotifyEvent contains the following key components:

Property Description

getDomain()

Returns the Trackable entity instance that was mutated.

getRepository()

Returns the NotificationStateRepository responsible for the mutation.

getContext()

Returns the ContextInfo associated with the request, providing sandbox, catalog, and application details.

additionalParameters

A Map<String, String> that can be used to pass extra metadata along with the event.

Implementation

To listen for these events, implement the Spring ApplicationListener interface:

import com.broadleafcommerce.data.tracking.core.service.MutationNotifyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class MyMutationListener implements ApplicationListener<MutationNotifyEvent> {

    @Override
    public void onApplicationEvent(MutationNotifyEvent event) {
        Trackable domain = event.getDomain();
        ContextInfo context = event.getContext();

        if (domain instanceof JpaProduct) {
            // Handle product mutation
        }
    }
}

Best Practices

  • Filter by Level: In many cases, you only want to react to changes that have reached the PRODUCTION level. You can check this via the entity’s tracking information:

    if (TrackingLevel.PRODUCTION.getLevel().equals(domain.getTracking().getLevel())) {
        // React to production change
    }
  • Differentiate Operations: If you need to know if the operation was a CREATE, UPDATE, or DELETE, you may need to inspect the OperationType if it was passed in additionalParameters, or derive it from the entity state (e.g., checking if it’s archived for a delete).

  • Error Handling: Since this is a synchronous event by default, any exception thrown in your listener will propagate back to the service operation. If your side effect is non-critical, wrap it in a try-catch or use @Async on your listener method.

  • Decoupling: Using MutationNotifyEvent is the safest way to implement side effects across framework upgrades, as it decouples your custom logic from the core service implementations.