Use Interceptors in SAP Hybris
1. Overview
A Model in Hybris has a lifecycle managed by the ModelService
(Create, Update, Load, Remove).
Hybris offers interceptors that provide the possibility to Hook into model lifecycle to be able to act when an event occurs.
In this article, I will show you the various types of interceptors in Hybris and how to create them.
In the next section of this article we will create interceptors for
UserModel
.
2. Implementation
2.1. Create InitDefaultsInterceptor
The InitDefaultsInterceptor
is called when ever you create a new model using modelService.initDefaults()
or modelService.create()
.
1. Create a Java class implements InitDefaultsInterceptor
and override onInitDefaults()
method.
package com.stackextend.core.interceptors;
// imports...
public class UserInitDefaultInterceptor implements InitDefaultsInterceptor<UserModel> {
@Override
public void onInitDefaults(UserModel userModel, InterceptorContext interceptorContext) throws InterceptorException {
// do what ever business logic you want here...
System.out.println("You are trying to create/init UserModel: " + userModel.toString());
}
}
2. Register the UserInitDefaultInterceptor
as a bean in Spring.
<!-- ...\hybris\bin\custom\training\trainingcore\resources\trainingcore-spring.xml -->
<bean id="userInitDefaultInterceptor" class="com.stackextend.core.interceptors.UserInitDefaultInterceptor">
<!-- inject beans here if needed -->
</bean>
3. Declare and configure your interceptor using InterceptorMapping
.
<bean id="userInitDefaultInterceptorMapping" class="de.hybris.platform.servicelayer.interceptor.impl.InterceptorMapping">
<property name="interceptor" ref="userInitDefaultInterceptor"/>
<property name="typeCode" value="User"/>
</bean>
4. Create a new instance of UserModel
to see your interceptor being executed.
// 1. This is one way to invoke the InitDefaultInterceptor
UserModel newUser = new UserModel();
modelService.initDefaults(newUser);
// 2. This is another way to invoke the InitDefaultInterceptor
UserModel newUser = modelService.create(UserModel.class);
2.2. Create LoadInterceptor
The LoadInterceptor
is invoked just after a model is being retrieved from the database, using modelService.get()
for example.
1. Create a Java class implements LoadInterceptor
and override onLoad()
method.
package com.stackextend.core.interceptors;
// imports....
public class UserLoadInterceptor implements LoadInterceptor<UserModel> {
@Override
public void onLoad(UserModel userModel, InterceptorContext interceptorContext) throws InterceptorException {
// do what ever business logic you want here...
System.out.println("This UserModel is just being loaded: " + userModel.toString());
}
}
2. Register the UserLoadInterceptor
as a bean in Spring.
<!-- ...\hybris\bin\custom\training\trainingcore\resources\trainingcore-spring.xml -->
<bean id="userLoadInterceptor" class="com.stackextend.core.interceptors.UserLoadInterceptor">
<!-- inject beans here if needed -->
</bean>
3. Declare and configure your interceptor using InterceptorMapping
.
<!-- ...\hybris\bin\custom\training\trainingcore\resources\trainingcore-spring.xml -->
<bean id="userLoadInterceptorMapping" class="de.hybris.platform.servicelayer.interceptor.impl.InterceptorMapping">
<property name="interceptor" ref="userLoadInterceptor"/>
<property name="typeCode" value="User"/>
</bean>
4. The UserLoadInterceptor
will be invoked when ever a UserModel
is being retrieved from the database.
// The userLoadInterceptor will be invoked here
UserModel userModel = modelService.get(null);
2.3. Create RemoveInterceptor
The RemoveInterceptor
is called before a model is being removed from the database.
1. Create a Java class implements RemoveInterceptor
and override onRemove()
method.
package com.stackextend.core.interceptors;
// imports...
public class UseRemoveInterceptor implements RemoveInterceptor<UserModel> {
@Override
public void onRemove(UserModel userModel, InterceptorContext interceptorContext) throws InterceptorException {
// do what ever business logic you want here...
System.out.println("This UserModel will be removed from the database: " + userModel.toString());
}
}
2. Register and declare the UseRemoveInterceptor
as bean in Spring like the previous examples.
3. The UserRemoveInterceptor
will be invoked when ever you remove a UserModel
from the database.
// The UserRemoveInterceptor will be invoked right here
modelService.remove(userToBeRemove);
2.4. Generalization
There are also PrepareInterceptor
and ValidateInterceptor
, they are called just before a model is being saved to the database, for example when modelService.save()
is used.
The ValidateInterceptor
is always invoked after PrepareInterceptor
.
Software Craftsmanship, Stackextend author and Full Stack developer with 6+ years of experience in Java/Kotlin, Java EE, Angular and Hybris…
I’m Passionate about Microservice architectures, Hexagonal architecture, Event Driven architecture, Event Sourcing and Domain Driven design (DDD)…
Huge fan of Clean Code school, SOLID, GRASP principles, Design Patterns, TDD and BDD.
Thanks for sharing. It’s very helpful.
Hi Ashish, thanks for getting in touch and glad that you found it helpful 🙂
Hey Mouad!
Could you please explain the PersistenceOperation approach?
What is the difference between PersistenceOperation.SAVE and just writing modelService.save()?
Thank you!
Hello, It’s used to avoid the infinite call of interceptors,
E.g: let’s suppose we have a
PrepareInterceptor
on theProductModel
and inside that interceptor, we callmodelService.save(product)
, hence ourPrepareInterceptor
will be called again and again.As always, thank you so much for the quick and clear answer!
Hi Mouad,
I run into a problem, I add some logical code in CustomerLoadInterceptor to modify the attribute value of customer model, when I call customer.getXX() by groovy in hac, it’ll execute the logical code in CustomerLoadInterceptor, but when I call it by postman, the code I added in CustomerLoadInterceptor do not execute. why?
what would be the exact error we might find, if an interceptor is not mapped with model?
In the above diagram LoadInterceptor is missed and used the “InitDefaultsInterceptor” twice. You need to correct it. Thanks in advance.
I have.a question when we intercept a item type. Will itssubtypes also be intercepted internally or we have to explicitly intercept to it sub types..
And how we can achieve intercepting subtypes of items at the interceptor level.
The interceptor will be applied to its subtypes as well by default.
If you want to skip this you need to do that inside the interceptor logic.
Hi, great article.
But please fix the first diagram. On get we call LoadInterceptor.
onGet or OnLoad is from LoadInterceptor, But in the above diagram you mentioned both as InitDefaultsInterceptor can you cross check once and Correct it.