Difference between <itemtype generate="false"> and <model generate="false"/> in Hybris Models - sap-commerce-cloud

I wanted to understand the difference between and in Hybris for Model creation. How do they function internally?

<model generate="false"/> can be used in some contexts:
1) In <itemtype> to exclude the type from being created (including all subtypes) and can be used like in this example:
<itemtype ....>
<model generate="false"/>
</itemtype>
2) In <attribute> context to exclude the attribute from being created. The result is that neither the private field nor getter and setter methods are generated!
<attribute ...>
<model generate="false"/>
</attribute>
I didn't found any utility yet for this case.
The <itemtype generate="false/true"/> is used to specify to generate the Java class files or not (for getters/setters).
You can read here more information about <model/> tag (create custom getters/setters/constructors for an itemtype)

Related

How to move the data from the supertype to the subtype in Hybris?

I added a new attribute to my custom model (CustomApparelProduct), which extends from ApparelProduct model. ApparelProduct already extends ProductModel (SAP core model).
extension-items.xml
<typegroup name="Apparel">
<itemtype code="ApparelProduct" extends="Product"
autocreate="true" generate="true"
jaloclass="de.hybris.training.core.jalo.ApparelProduct">
<description>Base apparel product extension that contains additional attributes.</description>
<attributes>
<attribute qualifier="genders" type="GenderList">
<description>List of genders that the ApparelProduct is designed for</description>
<modifiers/>
<persistence type="property"/>
</attribute>
</attributes>
</itemtype>
<itemtype code="CustomApparelProduct" extends="ApparelProduct"
autocreate="true" generate="true" > // My custom type
<description> Custom Apparel Product that contains total amount attributes</description>
<attributes>
<attribute qualifier="amount" type="java.lang.Integer">
<description>Total buying amount </description>
<modifiers/>
<persistence type="property"/>
<defaultvalue>Integer.valueOf(0)</defaultvalue>
</attribute>
</attributes>
</itemtype>
When I go to Hybris Admin Console to check the data from my new Types by using FlexibleSearch, the result is that all the fields lack data. ( The picture below is from my CustomApparelProduct type)
When I check the FlexibleSearch for ApparelProduct type and Product type, the result is that all the fields hava data. ( The picture below is from ApparelProduct type)
I don't know what I need to transfer the original data from Product to my new type CustomApparelProduct. The original data was inserted to system using impex and csv file; the type used to insert is Product.
How I can transfer thedata to my custom type?
You cannot change from Type A to Type B easily/directly.
You need to migrate the data. i.e. Delete Type A item. Re-insert/create item as Type B. Also, check if there are other dependencies that need to be updated.

SAP Hybris 1905 - Update OOTB 'relation'

I'm looking at updating an OOTB 'relation', just wanted to add 'ordered=true'.
OOTB
\hybris\bin\modules\commerce-services\commerceservices\resources\commerceservices-items.xml
<relation code="PoS2WarehouseRel" localized="false"
generate="true" autocreate="true">
<description>This relation determines available warehouses for the point of service.</description>
<deployment table="PoS2WarehouseRel" typecode="6217" />
<sourceElement qualifier="pointsOfService" type="PointOfService"
cardinality="many" />
<targetElement qualifier="warehouses" type="Warehouse"
cardinality="many" collectiontype="list" />
</relation>
In my extension core, myextncore-items.xml, I overwrote the OOTB relation,
<relation code="PoS2WarehouseRel" localized="false"
generate="true" autocreate="false">
<description>This relation determines available warehouses for the point of service.</description>
<sourceElement qualifier="pointsOfService" type="PointOfService"
cardinality="many" />
<targetElement qualifier="warehouses" type="Warehouse"
cardinality="many" collectiontype="list" ordered="true"/>
</relation>
But getting error - [ycheckdeployments] No deployment defined for relation PoS2WarehouseRel
Then I tried, Updating to a new code name, added a 'deployment' element,
<relation code="PoS2WarehouseRelNew" localized="false"
generate="true" autocreate="true">
<description>This relation determines available warehouses for the point of service.</description>
<deployment table="PoS2WarehouseRelNew" typecode="13000" />
<sourceElement qualifier="pointsOfService" type="PointOfService"
cardinality="many" />
<targetElement qualifier="warehouses" type="Warehouse"
cardinality="many" collectiontype="list" ordered="true"/>
</relation>
This time getting error - java.lang.UnsupportedOperationException: Attribute warehouses from PoS2WarehouseRelNew relation is already declared in Warehouse
How do I define/update a relation between 'pointsOfService' and 'warehouses' ?
Maybe the example here helps:
https://help.sap.com/viewer/d0224eca81e249cb821f2cdf45a82ace/1905/en-US/bae7ed9732a4423f867114217ae21b46.html
In that example they redeclared the Collection attribute on one end of the itemtype. But looks hacky...
UPDATE: The given link included relationType has ordered property but xsd file hasn't got. I haven't tried this yet, may be compiler give an error.
Relations haven't got ordered attribute. ordered attribute exist on collections. You can check xxx-item.xml file schema item.xsdin module folder.
I've encountered the same problem. No deployment was defined and when i did - got the same exception. In my case it was all about changing name in qualifier.
In this case i would change it to "posWarehouses" ;)

Redefining data type in items.xml in Hybris

I had a datatype defined as follows in items.xml:
<attribute qualifier="daysOfWeek" type="java.lang.String">
<persistence type="property" />
</attribute>
To modify the data type to enumeration,I redefined it as follows:
<enumtype code="DaysOfWeek" autocreate="true" generate="true">
<value code="Monday" />
<value code="Tuesday" />
</enumtype>
<attribute qualifier="daysOfWeek" type="DaysOfWeek">
<persistence type="property" />
</attribute>
After updating the extension,I am getting SQLException.Is there anything wrong with this approach?
hybris doesn't support updates like this in a "running" system.
The reason is that hybris won't drop any db columns and recreate them as any data contained in there would be lost (plus its probably difficult to write this logic for multiple supported databases).
If you are in a development phase of your project, the easiest way to fix this is to initialize your system from scratch (i.e. it will drop the database and recreate it).
If you have a live system / production system, you would have to take another approach:
You would define a new attribute (different name!) with your enumeration type.
You would then probably update any code to use the new field.
You would also have to take care of data migration, i.e. write some scripts that transfer the old data (e.g. the String "Monday" to the new respective enum value).
Hope this helps!

how to redeclare core model attribute type without extending it in Hybris

By default Hybtis gives CreditCardType as a mandatory attribute. I want to make it Optional by using redeclare=true (without extending it with new model). I am wondering why its not updating CreditCardPaymentInfo model. I am doing like this
<itemtype code="CreditCardPaymentInfo" autocreate="false" generate="false" >
<attributes>
<attribute qualifier="type" type="CreditCardType" redeclare="true" autocreate="false" generate="true">
<modifiers read="true" write="true" search="true" optional="true" />
<persistence type="property"/>
</attribute>
</attributes>
</itemtype>
My ant build is working fine. But whenever i m updating running system, Hybris is not making this attribute non mandatory.
In case if I am extending it with my custom model and re-declaring it then its working, but that's what i don't need. I just want to make it optional without extending it.
I think its possible with Impex also, but i don't know the way. Please help.
You can't redeclare an attribute without extending a type.
The documentation for redeclare says it clearly:
Lets you re-define the attribute definition from an inherited type. In
essence, you can use a different type of attribute as well as
different modifier combinations than on the supertype.
Impex to the rescue. You can alter attribute modifiers with an impex afterwards.
Place following impex script
update AttributeDescriptor;enclosingType(code)[unique=true];qualifier[unique=true];optional
;CreditCardPaymentInfo;type;true
under <your-extension>/resources/impex/essentialdata-<chosse-a-name>.impex.
On each typesystem update (or initialize) this impex gets executed and marks CreditCardPaymentInfo.type as optional. For testing purpose, you can run this script within hac, too.

Hybris - overriding existing unique attributes of an Item Type to make them non-unique

In my hybris application, I wanted to override my CustomerReview item type so that its attributes product and user are not unique anymore.
The uniqueness of these attributes are declared in the relationships between CustomerReview and Product/User. I tried adding the relationship declaration again to my extname-items.xml file and set the appropriate unique="false" attributes, as follows:
<relation generate="false" localized="false" code="ReviewToUserRel" autocreate="false">
<sourceElement type="User" qualifier="user" cardinality="one">
<modifiers write="false" initial="true" optional="false" unique="false" />
</sourceElement>
<targetElement type="CustomerReview" qualifier="customerReviews" cardinality="many">
<modifiers write="false" initial="true" />
</targetElement>
</relation>
This doesn't do the trick though. After I rebuild the application and Update the Running System, the user and product attributes of a CustomerReview are still unique attributes.
So what's the best solution for this problem?
It's true that rewriting the relation will not override it.
Another way to solve it would be to add an attribute to the type and set that as unique. For instance emailAddress:
<itemtype code="CustomerReview" autocreate="false" generate="false">
<attributes>
<attribute type="java.lang.String" qualifier="email">
<persistence type="property" />
<modifiers read="true" write="true" unique="true"/>
</attribute>
</attributes>
</itemtype>
Then you could have multiple reviews from the same user for the same product, as long as the emailAddress differs.
Updating the relation will not overwrite the existing relation. Better create new item definition for CustomerReview and then relate this with product.

Resources