Dynamic Attribute
- 19th Nov 2016
- 26
- 105460
- define dynamic attribute in hybris Dynamic attributes in Hybris Dynamic enum in hybris How to define dynamic attribute in hybris how to make attribute as dynamic in hybris what is dynamic attribute in hybris what is the difference between persistent type and dynamic type in hybris in items.xml
As we all know that any attribute we define in item type will have a tag called persistent type.
- persistent type=”property”
persistent type=”property”
In this case,
Corresponding column will be created in the database and hence the values will be stored in the DB. So it’s called persistent attribute.
- persistent type=”dynamic”
persistent type=”dynamic”
In this case,
There will be no column created in the database and hence values will not be stored in the database.
So it’s called Non persistent or dynamic attribute.
For every dynamic attribute we define, we need to mention the attribute handler otherwise Bean Id will be generated automatically and we have to use the same bean id while defining Spring bean in XML.
Attribute handler is implemented using Spring.
So we need to mention the spring bean id for the attribute handler.
Then we need to define the class for that spring bean id which provides the custom logic for the dynamic attribute.
Note:
It is possible that one item type can have any number of dynamic attributes.
Requirement:
Identify how old the customer is in our site so that we can give some discount to those customers who are 3 years old.
How to achieve it?
We need to get the customer’s registration date which we store as creation_time in DB and we need to get current time from Java Date API.
We need to do current_time – creation_time to know how old the customer is.
We can add a new attribute called “customer_site_age” as dynamic attribute.
Let’s see the steps for the same.
Step 1:
Define a new attribute in the items.xml for Customer item type and make it as dynamic attribute.
- <itemtype code="Customer" autocreate="false" generate="false">
- <description>Extending Customer type with additional attributes.</description>
- <attributes>
- <attribute autocreate="true" qualifier="customer_site_age" type="java.lang.Integer">
- <modifiers read=”true” write="true"/>
- <persistence type="dynamic"/>
- <description>Dynamic attribute for customer site age</description>
- </attribute>
- </attributes>
- </itemtype>
<itemtype code="Customer" autocreate="false" generate="false"> <description>Extending Customer type with additional attributes.</description> <attributes> <attribute autocreate="true" qualifier="customer_site_age" type="java.lang.Integer"> <modifiers read=”true” write="true"/> <persistence type="dynamic"/> <description>Dynamic attribute for customer site age</description> </attribute> </attributes> </itemtype>
Here we have defined the persistent type as dynamic.
Step 2:
Define the Attributehandler which should be the bean id of the class which implements DynamicAttributeHandler.
- <itemtype code="Customer" autocreate="false" generate="false">
- <description>Extending Customer type with additional attributes.</description>
- <attributes>
- <attribute autocreate="true" qualifier="customer_site_age" type="java.lang.Integer">
- <modifiers write="false"/>
- <persistence type="dynamic" attributeHandler="customerSiteAge"/>
- <description>Dynamic attribute for customer site age</description>
- </attribute>
- </attributes>
- </itemtype>
<itemtype code="Customer" autocreate="false" generate="false"> <description>Extending Customer type with additional attributes.</description> <attributes> <attribute autocreate="true" qualifier="customer_site_age" type="java.lang.Integer"> <modifiers write="false"/> <persistence type="dynamic" attributeHandler="customerSiteAge"/> <description>Dynamic attribute for customer site age</description> </attribute> </attributes> </itemtype>
We have added attributeHandler=”CustomerSiteAge” in the persistent tag.
Step 3:
Define the class with custom logic
We can define the new class either by extending AbstractDynamicAttributeHandler or by implementing DynamicAttributeHandler
Define it in the trainingcore(your custom core) extension in org.training.core.attributes package
- public class CustomerSiteAgeHandler extends
- AbstractDynamicAttributeHandler<Integer, CustomerModel>
- {
- @Override
- public Integer get(final CustomerModel model)
- {
- int customerSiteAge = 0;
- try
- {
- final Date customerRegisteredDate = model.getCreationtime();
- final Calendar cal = Calendar.getInstance();
- cal.setTime(customerRegisteredDate);
- final int registeredYear = cal.get(Calendar.YEAR);
- final int currentYear = Calendar.getInstance().get(Calendar.YEAR);
- customerSiteAge = currentYear - registeredYear;
- }
- catch (final Exception e)
- {
- e.printStackTrace();
- }
- return customerSiteAge;
- }
- }
public class CustomerSiteAgeHandler extends AbstractDynamicAttributeHandler<Integer, CustomerModel> { @Override public Integer get(final CustomerModel model) { int customerSiteAge = 0; try { final Date customerRegisteredDate = model.getCreationtime(); final Calendar cal = Calendar.getInstance(); cal.setTime(customerRegisteredDate); final int registeredYear = cal.get(Calendar.YEAR); final int currentYear = Calendar.getInstance().get(Calendar.YEAR); customerSiteAge = currentYear - registeredYear; } catch (final Exception e) { e.printStackTrace(); } return customerSiteAge; } }
Step 4:
Associate the attribute handler specified in items.xml with spring bean id in trainingcore-spring.xml(your_custom_core-spring.xml)
- <bean id="customerSiteAge"
- class="org.training.core.attributes.CustomerSiteAgeHandler"/>
<bean id="customerSiteAge" class="org.training.core.attributes.CustomerSiteAgeHandler"/>
Note:
customerSiteAge mentioned as spring bean id above should be same as attributeHandler mentioned in items.xml.
Step 5:
Build and then update the system either using HAC or using ant command
Now whenever we access customer Model, we can also access the customerSiteAgeattribute from customer model,
we will get the result of our custom logic in that attribute.
We can display it in any UI page by setting its value in appropriate controller and model attribute.
Advantages of Dynamic attribute
Data will not be saved in DB as its dynamic
The custom logic is written once and used all the time wherever that attribute is required.
When we should go for Dynamic attribute?
We should choose dynamic attribute whenever we want to get some derived data based on existing values.
So instead of saving one more column, we can make it as dynamic and compute its value based on the current values.
Dynamic in Enum?
Dynamic in enum is completely different from Dynamic attributes.
If an Enumtype is non-dynamic (by default, dynamic=”false”) we are not allowed to add new values at runtime.
If we add any non-dynamic enumtype without values,build will fail as it does not have any effect.
So if you want to add new values at runtime we have to make dynamic=”true” for an enum.
We can change the flag anytime but enforces a system update.
If dynamic=”false” the servicelayer generates real java enums (having a fixed set of values).
If dynamic=”true” it generates hybris enums which can be used without fixed values(means we can add run time values).
as it’s dynamic attribute then why autocreate written as true ?
<attribute autocreate="true" ……
?
because dynamic attribute column do not create in table , right ?
very nice.easily understandable.can u plzz write a blog on groovy script in brief
Thanks, You can find the same here !
http://javainsimpleway.com/groovy-scripts-overview/
Can we implement some custom logic inorder save/change other persistent attributes ,in set method of attributehandler of dynamic attribute
It was very nice explanation and helped me a lot.But
Can u plz help me on, how to add new values at run time for dynamic enumtypes?
I will be waiting for ur reply.
Thanks in Advance.
we have java class CustomerDate in ext-facade.
Now i want add new attribute in CustomerDate class which is Data object.
How to do this.plse explain with psudo code
Sir plse let me known.
Hi KB,
As we know no columns are created for dynamic values and hence they are not stored in DB, then why do we set autocreate=”true” for dynamic attribute? Can you please explain.
Thanks in advance.
you are right, attribute defined as dynamic will not have values persisted to db.
But setting autocreate to ‘true’, the attribute descriptor will be created used internally by hybris not column in the table.
Hi!
Great job!
Is it possible to make search (in backoffice) somehow by the dynamic attribute?
Thanks in advance!
No, I don’t think so as Dynamic attribute value is obtained from attribute handler java class.
If no validation is done for the dynamic attribute, how to create the attribute handler?
Hi Karibasappa,
The explaination was so fluid and easy to understand unlike wiki. Thanks for teh same.
Is it possible to use these dynamic attributes in backoffice (in advanced-search, list-view et.,)?
If so can you explain how (better to add it as answer byb editing than in the comment)
Regards,
Ram
can you explain why you have given modifier write=true for a dynamic attribute?
as per my understanding it does not make any sense to set the value of a dynamic attribute.
It is write=false
KB can you please explain this point :
“For every dynamic attribute we define, we need to mention the attribute handler otherwise Bean Id will be generated automatically and we have to use the same bean id while defining Spring bean in XML.”
What is the specific point that you are not understanding on this ?
If bean id is generated automatically then how to get that bean id as it is generated automatically?
Automatically generated bean id has a fixed naming standard which is as below
ItemtypeCode_attributeQualifierAttributeHandler.
For example, the bean ID for the Dynamic Attribute with the qualifier siteAge for the Customer type is Customer_siteAgeAttributeHandler
So…we will give the same “Customer_siteAgeAttributeHandler” bean configuration at the time bean declaration.
Very Nice Help Me alot
Keep it up
Very good and detailed explanation, helped me a lot.
Thank you !!
Thanks you very much this helps a lot
Thank you !!
Excellent explanation KB. Keep up the good work. Only passionate and good hearted(or soul) people will share the knowledge like this. God bless you.
Thanks Magesh !
Happy learning !!