Interceptor Generator

Pick an item type and which lifecycle phases to hook into -- get the interceptor class, its Spring bean, and the InterceptorMapping registration.

🔒 Your code never leaves your browser — everything is generated locally from templates, no AI, no server round-trip.

  • Item type is required.
  • Class name is required.
The items.xml typeCode this interceptor is mapped to, e.g. Product.

Interceptor types

Controls run order when multiple interceptors map to the same type/phase -- lower runs first.
trainingcore/src/com/prospect2p/core/interceptors/MyInterceptor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.prospect2p.core.interceptors;

import de.hybris.platform.servicelayer.interceptor.InterceptorContext;
import de.hybris.platform.servicelayer.interceptor.InterceptorException;
import de.hybris.platform.servicelayer.interceptor.LoadInterceptor;
import de.hybris.platform.core.model.product.ProductModel;

public class MyInterceptor implements LoadInterceptor {

    @Override
    public void onLoad(final Object model, final InterceptorContext ctx) throws InterceptorException {
        // Runs every time an item of this type is loaded from the database.
        final ProductModel product = (ProductModel) model;

        // TODO: implement onLoad logic for Product
    }
}
Generated scaffold. Review and test before using in production.
Advertisement

What is an Interceptor in SAP Commerce?

An Interceptor in SAP Commerce (Hybris) is a class that plugs into an item type's persistence lifecycle -- loading, initializing defaults, preparing to save, validating, and removing. Each phase has its own interface (LoadInterceptor, InitDefaultsInterceptor, PrepareInterceptor, ValidateInterceptor, RemoveInterceptor), and a single class can implement as many of them as it needs.

Interceptors are registered against a specific item type (via typeCode) with an InterceptorMapping, and the servicelayer invokes the matching method automatically whenever an item of that type (or a subtype) goes through that lifecycle phase -- no explicit call site in your business code.

When to use it

Use an interceptor for cross-cutting logic that must run no matter how an item is saved -- from Backoffice, an ImpEx import, a REST call, or a batch job. Common uses: defaulting attributes on create (InitDefaults), deriving/normalizing values before save (Prepare), enforcing business rules (Validate), or blocking/cleaning up on delete (Remove).

Prefer a Populator or service-layer code instead when the logic only needs to run from one specific code path (e.g. one OCC endpoint) -- an interceptor runs for every save of that type, everywhere, which is powerful but also easy to misuse for something that should be narrower.

Files generated

  • The interceptor class implementing the selected interceptor interface(s), with one method stub per selected phase.
  • A Spring bean registering the class.
  • An InterceptorMapping bean wiring the interceptor to the target item type's typeCode, with an optional order.

Step-by-step: how to use the output

  1. Copy the Java class into <extension>/src/<package>/interceptors/ and fill in the TODO in each selected method.
  2. Copy the two <bean> elements into your extension's -spring.xml (or merge them into an existing <beans> block).
  3. Rebuild and restart, then exercise the lifecycle phase you implemented (e.g. save the item in Backoffice) to confirm it fires.
  4. If multiple interceptors target the same type and phase, set "order" on each InterceptorMapping to control the sequence they run in (lower runs first).

Common mistakes

  • Forgetting that the mapping's typeCode applies to subtypes too -- an interceptor mapped to "Product" also fires for every custom product subtype unless you guard for the exact type inside the method.
  • Doing expensive work (remote calls, heavy queries) inside onLoad or onPrepare -- these can run very frequently (once per load/save) and will show up as a performance problem across the whole system, not just one feature.
  • Throwing an unchecked exception instead of InterceptorException from onValidate -- InterceptorException is the type the servicelayer actually expects and surfaces cleanly back to the caller (Backoffice, ImpEx, etc).
  • Relying on interceptor order between two unrelated interceptors without setting "order" explicitly -- without it, the sequence isn't guaranteed and can change across deployments.

Frequently asked questions

Can one interceptor class implement multiple interceptor interfaces?

Yes -- that's the normal pattern. Implement LoadInterceptor, PrepareInterceptor, ValidateInterceptor etc. on the same class and register it with one InterceptorMapping; the servicelayer calls whichever method matches the phase it's in.

What's the difference between PrepareInterceptor and ValidateInterceptor?

Both run just before persisting, but PrepareInterceptor is for deriving/normalizing attribute values (it can still change the item), while ValidateInterceptor is for rejecting an invalid save by throwing InterceptorException -- by convention it shouldn't mutate the item, only check it.

Does an interceptor fire for ImpEx imports too?

Yes. Interceptors run at the servicelayer persistence level, so they fire for saves coming from Backoffice, ImpEx, REST/OCC, and custom business code alike -- that's exactly what makes them useful for rules that must never be bypassed.

How do I stop an interceptor from firing on a subtype?

Check the concrete type inside the method (e.g. model.getItemtype() or an instanceof check against the subtype's Model class) and return early, since InterceptorMapping's typeCode match includes all subtypes by design.

Why isn't my RemoveInterceptor stopping the delete?

Throwing InterceptorException from onRemove is what blocks the removal -- if the method just logs or returns normally, the delete proceeds. Make sure the exception is actually thrown on the condition you want to block.

🗳️ Vote for the next SAP Commerce guide

Vote or suggest a topic
What should we write next? Vote