cancel
Showing results for 
Search instead for 
Did you mean: 

How to Redeclare a Relationship?

Former Member
0 Kudos

I am wondering how one might go about redeclaring a relationship in order to make one side of it no longer optional. Is there an equivalent for relations to the redeclare="true" option with attributes?

Our example is that we've created a subtype of SubscriptionProduct called MySubsProduct. Our subtype requires that a SubscriptionEntitlement be set for the site to work correctly, but it is not defined with in its original definition in subscriptionservices-items.xml. I have tried copy/pasting the relation definition from subscriptionservices-items.xml into my custom-items.xml, adding the optional modifier to the SubscriptionEntitlement side, building, and running an Update, but when viewing from the MySubsProduct or SubscriptionProduct Properties in "Types" in the hMC, they are both still considered optional.

Code snippet of what I added to my custom-items.xml:

 <relation localized="false" generate="false" code="SubscriptionProduct2SubscriptionEntitlementsRelation" autocreate="false">
     <sourceElement type="SubscriptionProduct" qualifier="subscriptionProduct" cardinality="one">
         <modifiers optional="false"/>
     </sourceElement>
     <targetElement type="SubscriptionEntitlement" qualifier="subscriptionEntitlements" cardinality="many">
         <modifiers optional="false"/>
     </targetElement>
 </relation>

I am fine either way if we make the SubscriptionEntitlement required on MySubsProduct only, or if it is required on both SubscriptionProduct as well as its subtypes (including MySubsProduct), but I can't seem to figure out how to do this without having to change the original relationship definition in subscriptionservices-items.xml.

Former Member
0 Kudos

Did you find a solution for this? I am looking for the similar issue where I need to make a relation optional

Thanks,

jurijs_sulins
Discoverer
0 Kudos

Hey, any updates on this?

Accepted Solutions (1)

Accepted Solutions (1)

Former Member

The correct way to redeclare an attribute is inside the sub type declaration. This also covers relation attributes. Have a look at this example where I created a sub type of Agreement, which has an optional relation attribute Agreement.catalogVersion:

 <itemtype 
    code="MyAgreement" 
    jaloclass="de.hybris.platform.catalog.jalo.MyAgreement" extends="Agreement">
             <attributes>
                 <attribute qualifier="catalogVersion" type="CatalogVersion" redeclare="true">
                     <modifiers read="true" write="true" search="true" optional="false"/>
                     <persistence type="property"/>
                 </attribute>
             </attributes>
         </itemtype>

After initialization or update I have the new type MyAgreement and when creating a new instance it shows that catalogVersion is mandatory: Hope this helps, Axel

Former Member
0 Kudos

Hi Axel, thanks four your reply.

As I understand your example refers to attributes - but how does this work for n:m or n:1 relations?

Regards, Norbert

Former Member
0 Kudos

I did refer to a relation. The key point is that each relation indirectly creates two attributes. In a sub type of the source or target type you can simply re-declare those attributes ( as I did ).

Just try my code sample: it's working and based on the CatalogVersion2Agreements relation.

Former Member
0 Kudos

This approach seems to have it's limitations, e.g. make existing relations sortable. For example, we need to be able to define the order of categories on a product. Therefore i quickly tried the following:

         <itemtype code="MyProduct" extends="Product">
             <attributes>
                 <attribute qualifier="supercategories" type="CategoryList" redeclare="true">
                     <persistence type="property" />
                 </attribute>
             </attributes>
         </itemtype>

While it's possible now to drag/drop the categories on the MyProduct instances, the changes aren't persisted in the database.

Former Member
0 Kudos

BTW, I tried this technique to change an attribute from non-optional to optional and it doesn't work. Seems to be using super.create() which calls the parent class that has is set as not optional and so disallows creation.

Answers (1)

Answers (1)

Former Member
0 Kudos

If you wish to overwrite it kindly mention generate="true" localized="false" autocreate="true" in the relation. Your code snippet would look like..

 <relation localized="false" generate="true" code="SubscriptionProduct2SubscriptionEntitlementsRelation" autocreate="true">
 <sourceElement type="SubscriptionProduct" qualifier="subscriptionProduct" cardinality="one">
 <modifiers optional="false"/>
 </sourceElement>
 <targetElement type="SubscriptionEntitlement" qualifier="subscriptionEntitlements" cardinality="many">
 <modifiers optional="false"/>
 </targetElement>
 </relation>

Update running system and check that.. This will work :)

Former Member
0 Kudos

This doesn't work, and causes a build failure:

java.lang.IllegalArgumentException: cannot merge namespace ((expcore)) into (()) due to duplicate type code 'subscriptionproduct2subscriptionentitlementsrelation' : SubscriptionProduct2SubscriptionEntitlementsRelation::((expcore))::YRelation[expcore-items.xml:111(RelationTypeTagListener)]<>SubscriptionProduct2SubscriptionEntitlementsRelation::((subscriptionservices))::YRelation[subscriptionservices-items.xml:142(RelationTypeTagListener)]

Therefore, I can't tell hybris to regenerate an existing relationship, but I don't want a second relation.

0 Kudos

Adam, how did you fix this?