Dynamic Attribute Generator

Describe a computed attribute once -- get the items.xml dynamic persistence snippet, the DynamicAttributeHandler class, and its Spring bean.

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

  • Item type is required.
  • Attribute qualifier is required.
  • Return type is required (e.g. java.math.BigDecimal).
Fully-qualified Java type, e.g. java.math.BigDecimal, java.lang.String, or boolean.
Used only to generate a TODO comment in get() -- not parsed or executed.
trainingcore/src/com/prospect2p/core/handlers/MyAttributeAttributeHandler.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.prospect2p.core.handlers;

import de.hybris.platform.servicelayer.model.attribute.DynamicAttributeHandler;
import de.hybris.platform.core.model.product.ProductModel;
import java.lang.String;

public class MyAttributeAttributeHandler implements DynamicAttributeHandler<String, ProductModel> {

    @Override
    public String get(final ProductModel model) {
        // TODO: compute the value of this attribute
        return null;
    }

    @Override
    public void set(final ProductModel model, final String value) {
        throw new UnsupportedOperationException("attribute is a read-only dynamic attribute");
    }
}
Generated scaffold. Review and test before using in production.
Advertisement

What is a Dynamic Attribute in SAP Commerce?

A dynamic attribute in SAP Commerce (Hybris) is an items.xml attribute with persistence type="dynamic" -- instead of being stored as a database column, its value is computed on the fly by a Java class (a DynamicAttributeHandler) every time the attribute is read (and optionally written).

The handler implements DynamicAttributeHandler<ValueType, ModelType> with get(model) and set(model, value), and is wired to the attribute via the attributeHandler bean id in items.xml -- the platform calls get()/set() transparently whenever code calls the generated getter/setter on the model.

When to use it

Use a dynamic attribute when a value should always be derived (from other attributes, related items, or external state) rather than stored -- e.g. a discounted price, an aggregated rating, or a computed status flag that must never go stale relative to its inputs.

Avoid it for anything expensive to compute that gets read often (it recomputes on every get() call, with no built-in caching) and for values that genuinely need their own query-able, indexable database column -- those should be real persisted attributes instead.

Files generated

  • An items.xml <attribute> snippet with persistence type="dynamic" and the attributeHandler bean id.
  • The DynamicAttributeHandler<ValueType, ModelType> implementation, with get() and set() stubs.
  • A Spring bean registering the handler.

Step-by-step: how to use the output

  1. Copy the <attribute> snippet into the matching <itemtype> block in your extension's -items.xml, then run a system update (ant updatesystem equivalent) to regenerate the model and getter/setter.
  2. Copy the handler class into <extension>/src/<package>/handlers/ and fill in the TODO inside get() (and set(), if read/write).
  3. Copy the <bean> element into your extension's -spring.xml.
  4. Rebuild, restart, and read the attribute via its generated getter (e.g. model.getDiscountedPrice()) to confirm the handler is invoked.

Common mistakes

  • Making a read-only attribute's items.xml modifiers say write="true" -- the generated setter will then silently exist but call a handler set() that was never meant to be invoked; the modifiers and the set() implementation need to agree.
  • Doing a heavy query or remote call inside get() without any caching -- every single read of the attribute re-runs it, including from list views and search results that read many items at once.
  • Forgetting the attributeHandler bean id in items.xml has to exactly match the Spring bean's id -- a typo there fails at startup/system update, not silently.
  • Trying to make a dynamic attribute searchable/sortable in a Solr index the same way a persisted attribute is -- dynamic attributes generally need their own indexing setup (e.g. a custom ValueProvider) since there's no backing column to index directly.

Frequently asked questions

Does a dynamic attribute get stored in the database?

No -- persistence type="dynamic" means there is no database column at all. The value is computed fresh by the handler's get() method every time it is read, and (if read/write) written via set() to wherever the handler chooses to persist it, if anywhere.

Can a dynamic attribute be read-only?

Yes, and it's the most common case -- set modifiers write="false" in items.xml and have the handler's set() throw UnsupportedOperationException, exactly as this generator does by default.

Why is my DynamicAttributeHandler generic type a wrapper class instead of a primitive?

Java generics don't allow primitives as type arguments -- a handler for a boolean-like value must declare DynamicAttributeHandler<Boolean, ...>, not <boolean, ...>, even though the getter still returns a primitive-compatible wrapper.

Can a dynamic attribute's value depend on other dynamic attributes?

Yes, but be careful of call chains and performance -- each nested dynamic attribute read triggers its own handler, so a get() that reads several other dynamic attributes can get expensive quickly with no caching layer in between.

How is this different from a Populator?

A Populator runs once, explicitly, when converting a model to a DTO in one specific code path. A dynamic attribute is invoked implicitly every time its getter is called, from any code, anywhere -- it behaves like a real model attribute rather than a one-off conversion step.

🗳️ Vote for the next SAP Commerce guide

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