Complete Guide of Converter and Populator in SAP Hybris

So far, we have learned that SAP hybris follows layered architecture and each layer uses a different type of object for data representation. Now, we will understand how data flows across different layers of the architecture. We know, we should NEVER expose Model objects directly outside the service layer. So, the big question is: how do we convert data from Model → DTO → WsDTO cleanly? This is where the SAP Commerce Converter and Populator come into play.

Converters and Populators form core design patterns in SAP Commerce (Hybris) that transform data between different layers of the application. Typically, they handle conversion between model objects (from the persistence layer) and DTOs (Data Transfer Objects) used in the service or storefront layers. These patterns promote code reusability and maintainability by separating the mapping logic and giving better control over what data is exposed or transferred across layers.

What is Converter and Populator?

A Converter is responsible for taking a source object, creating the target object, and coordinating the entire transformation process. It doesn’t map fields itself, instead, it delegates that work to multiple Populators and then returns a fully prepared object. In simple words, Converters create new instances of Data objects and call Populators to populate the data.

A Populator is a small, focused component that copies specific fields from the source to the target. Each Populator handles only one part of the data (like basic details, price, or stock), making the logic clean and reusable. The populator only fills data into the target object, it doesn’t return anything.

Basically, the Converter manages the overall conversion, while Populators do the actual step-by-step data mapping to build the final object. We use converters and populators in the facade layer, where we call the converter method by injecting the converter bean.

Let’s learn through different Scenario

If you are working in SAP Commerce (Hybris), understanding Converter and Populator is not enough – you should also know where and how they are used in real scenarios. In this blog, we cover all practical use cases of Converter and Populator in a simple and easy-to-understand way.

Scenario 1: Basic model to DTO conversion

  1. Create new attribute in model and DTO object

Add “eligible” attribute in ProductModel in *-items.xml


<itemtype code="Product" extends="GenericItem" autocreate="false" generate="false">
    <attributes>
        <attribute qualifier="eligible" type="java.lang.Boolean" autocreate="true" generate="true">
            <persistence type="property"/>
            <modifiers read="true" write="true"/>
		</attribute>
	</attributes>
</itemtype>

Add “eligible” attribute in ProductData bean in *-beans.xml


<bean class="de.hybris.platform.commercefacades.product.data.ProductData">
	<property name="eligible" type="java.lang.Boolean"/>
</bean>

Do the build. After the build, the system adds the eligible attribute to ProductModel.java and ProductData.java.

  1. Create Java class and implement Populator interface

public class ProductEligiblePopulator implements Populator<ProductModel, ProductData>
{
    public void populate(ProductModel source, ProductData target)
    {
        target.setEligible(source.getEligible());
    }
}
  1. Register populator bean in *-springs.xml

<alias name="defaultProductEligiblePopulator" alias="productEligiblePopulator"/>
<bean id="defaultProductEligiblePopulator" 
	  class="org.training.facades.populators.ProductEligiblePopulator" >
</bean>
  1. Define converter bean and define abstractPopulatingConverter as parent

<alias name="productEligibleConverter" alias="eligibleConverter"/> 
<bean id="productEligibleConverter" parent="abstractPopulatingConverter">
	<property name="targetClass" value="de.hybris.platform.commercefacades.product.data.ProductData"/>
	<property name="populators">
		<list>
			<ref bean="productEligiblePopulator"/>
		</list>
	</property>
</bean>
  1. Call converter in facade: In Facade layer we convert the model to Data by using Converter.convert() method.

Scenario 2: add via modifyPopulatorList

This scenario you will use most often as a Hybris developer. SAP Commerce provide many standard OOTB(out of the box) converters (e.g. productConverter, orderConverter). For example, when you add a new custom attribute “eligible” flag to a Product, you must ensure that attribute appears in the DTO on the storefront without redefining the entire converter stack.

Instead of defining a new converter from scratch, which we have done in last scenario, you use a special Spring configuration to intercept and inject your custom populator into an existing, Out-Of-The-Box (OOTB) converter list.

Follow first 3 steps from scenario 1. (i.e create attribute in model and DTO, create populator java class and register populator bean.)

Now the most important step, we have to do modifyPopulatorList spring configuration. It is a Spring configuration feature in SAP Commerce that allows you to dynamically add, remove, or reorder populators in an existing converter’s populator list—without modifying the original bean definition.


<bean parent="modifyPopulatorList">
	<property name="list" ref="productConverter"/>
	<property name="add" ref="productEligiblePopulator"/>
</bean>

Scenario 3: Remove a populator

Sometimes Hybris provides a Populator you don’t want. Maybe you don’t need stock information, or you have a custom one replacing the default. You can remove it. For remove also, we will use modifyPopulatorList.

NOTE: Removing a default populator might break other features that depend on that data being populated. So, always verify downstream effects.


<bean parent="modifyPopulatorList">
	<property name="list" ref="productConverter"/>
	<property name="remove" ref="productEligiblePopulator"/>
</bean>

Scenario 4: ConfigurablePopulator

A ConfigurablePopulator is a special type of populator that allows you to populate only selected fields dynamically at runtime, based on a given configuration (usually a set of options). It maps different populators to specific options, and based on the provided options at runtime, only relevant populators are executed.

Sometimes you don’t want to populate all fields every time, you want flexibility like on Product List Page(PLP) you want basic data and on Product Detail Page (PDP) you want detailed data. Instead of creating multiple converters, we use ConfigurablePopulator.

Let’s Populate ProductData based on options: BASIC (code, name), PRICE (price), STOCK (stock)

  1. Define options in *-beans.xml

<enum class="de.hybris.platform.commercefacades.product.ProductOption">
	<value>BASIC</value>
	<value>PRICE</value>
	<value>STOCK</value>
</enum>
  1. Create populators (ProductBasicPopulator, ProductPricePopulator, ProductStockPopulator)
  2. Register Populator beans in *spring.xml (productBasicPopulator, productPricePopulator, productStockPopulator)
  3. Configure ConfigurablePopulator

<bean id="productConfigurablePopulator" class="de.hybris.platform.converters.impl.ConfigurablePopulator">
    <property name="populators">
        <map>
            <entry key="BASIC" value-ref="productBasicPopulator"/>
            <entry key="PRICE" value-ref="productPricePopulator"/>
            <entry key="PRICE" value-ref="productStockPopulator"/>
        </map>
    </property>
</bean>

In this scenario, I use a ConfigurablePopulator to populate DTO fields dynamically based on a set of options. Each option is mapped to a specific populator, allowing me to control which data gets populated at runtime. This makes the implementation flexible and optimized for different use cases like listing and detail views.

Scenario 5: override existing populator

If you don’t want to remove the existing populator but still want to “override” behavior, then the clean way is replace its bean with your custom class. (If you want to use some logic from OOTB populator, then extends that populator).

  1. Identify OOTB populator spring configuration

<alias name="defaultGenderDataPopulator" alias="genderDataPopulator"/>
<bean id="defaultGenderDataPopulator" class="de.hybris.platform.yacceleratorfacades.populators.GenderDataPopulator" >
	<property name="typeService" ref="typeService"/>
</bean>
  1. Create custom populator

public class GenderDataPopulator implements Populator<Gender, GenderData>
{
	private TypeService typeService;
	protected TypeService getTypeService()
	{
		return typeService;
	}
	@Required
	public void setTypeService(final TypeService typeService)
	{
		this.typeService = typeService;
	}
	@Override
	public void populate(final Gender source, final GenderData target)
	{
		target.setCode(source.getCode());
		target.setName(getTypeService().getEnumerationValue(source).getName());
	}
}
  1. Register custom populator with same bean id as OOTB populator

<alias name="defaultGenderDataPopulator" alias="genderDataPopulator"/>
<bean id="defaultGenderDataPopulator" class="org.training.facades.populators.GenderDataPopulator" >
	<property name="typeService" ref="typeService"/>
</bean>

Scenario 6: Reverse conversion

While the default direction is Model -> DTO (for storefront display), you often need the exact opposite. This is required when a customer updates their profile in the storefront, when an OCC (Omni-Commerce Connect) API receives JSON to create a cart, or when saving complex objects like a new shipping address.


public class CustomerReversePopulator implements Populator<CustomerData, CustomerModel>
{
	@Override
	public void populate(final CustomerData source, final CustomerModel target) throws ConversionException
	{
		target.setOriginalUid(source.getDisplayUid());
		target.setUid(source.getUid());	
	}
}

Leave a Reply

Your email address will not be published. Required fields are marked *