meta data for this page
  •  

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
sap_hybris_commerce:sap_hybris_persistence_mechanism [2019/08/26 16:31] – [Recommendations] Antonio Robirosasap_hybris_commerce:sap_hybris_persistence_mechanism [2022/11/25 08:06] (current) – [One to many relations] Antonio Robirosa
Line 91: Line 91:
     * The field can only be written once (initial=true)     * The field can only be written once (initial=true)
     * The field must be removed when the parent Item is removed (partof=true)     * The field must be removed when the parent Item is removed (partof=true)
 +
 +<WRAP center round important 100%>
 +Hybris don't trigger the remove interceptors when updating a partof relations. If a base product is updated with a **subset** of the variants which are on the database, **the missing variants will be removed** and you can't use a remove interceptor to prevent the deletion. This happens on SAP commerce 1905. \\
 +To really prevent the removal of products from the database you need a database trigger like the following one for Microsoft SQL Server:
 +<code>
 +return jaloSqlScriptService.runDeleteOrUpdateStatement("CREATE OR ALTER TRIGGER PRODUCTS_DEL ON products INSTEAD OF DELETE AS THROW 51000, 'Products must not be deleted', 1")
 +
 +</code>
 +This code create database trigger preventing any removal of products. It depends on [[https://github.com/arobirosa/areco-deployment-script-manager/wiki|Areco Deployment Script Manager]]
 +
 +</WRAP>
 +
     * The field is part of the secondary key and must be **unique** inside the cluster of servers (unique=true). A group of attributes could be unique. The validation is done by Hybris using Java code. As two threads may store two items with the same unique values on the database, you have to use database transactions to be sure that the fields are unique across the cluster of servers     * The field is part of the secondary key and must be **unique** inside the cluster of servers (unique=true). A group of attributes could be unique. The validation is done by Hybris using Java code. As two threads may store two items with the same unique values on the database, you have to use database transactions to be sure that the fields are unique across the cluster of servers
     * [[https://help.hybris.com/6.5.0/hcd/8bff7a568669101488a5e40cb7bbd0b9.html#itemsxmlelementreference-type_modifierstype|Other modifiers]]     * [[https://help.hybris.com/6.5.0/hcd/8bff7a568669101488a5e40cb7bbd0b9.html#itemsxmlelementreference-type_modifierstype|Other modifiers]]
Line 174: Line 186:
 This example creates the column **customer** in the table where the items EmailAddress are stored and getters and setters on the customers to set and get the list of emails. The sourceElement and targetElement may have modifiers like the attributes. You have to read the source and target elements XML tags crossed to understand where the setters and getters are generated. This example creates the column **customer** in the table where the items EmailAddress are stored and getters and setters on the customers to set and get the list of emails. The sourceElement and targetElement may have modifiers like the attributes. You have to read the source and target elements XML tags crossed to understand where the setters and getters are generated.
  
 +One to many relations cannot be localized. You have to use a many to many relationship and manage the removal of associations.
 ===== Many to many relations ===== ===== Many to many relations =====
  
Line 229: Line 242:
 In every case you must use the **modelService**: In every case you must use the **modelService**:
  
-<code> +<code java
-@Component("deploymentScript2ExecutionConverter")public class DeploymentScript2ExecutionConverter implements Converter<DeploymentScript, ScriptExecutionModel> {  private static final Logger LOG = Logger.getLogger(DeploymentScript2ExecutionConverter.class);  @Autowired  private ModelService modelService;  /*   * (non-Javadoc)      * @see de.hybris.platform.servicelayer.dto.converter.Converter#convert(java.lang.Object)   */  @Override  public ScriptExecutionModel convert(final DeploymentScript source) throws ConversionException {    return this.convert(source, (ScriptExecutionModel) this.modelService.create(ScriptExecutionModel.class)); // Creation of a new item  }  /*   * (non-Javadoc)      * @see de.hybris.platform.servicelayer.dto.converter.Converter#convert(java.lang.Object, java.lang.Object)   */  @Override  public ScriptExecutionModel convert(final DeploymentScript source, final ScriptExecutionModel execution)      throws ConversionException {    ServicesUtil.validateParameterNotNullStandardMessage("source", source);    ServicesUtil.validateParameterNotNullStandardMessage("execution", execution);    if (DeploymentScript2ExecutionConverter.LOG.isDebugEnabled()) {      DeploymentScript2ExecutionConverter.LOG.debug("Creating an script execution model from the deployment script " + source);    }    execution.setExtensionName(source.getExtensionName());                                                         // The model is filled    execution.setScriptName(source.getName());    execution.setResult(null); // The caller must set the result before saving the execution.    execution.setPhase(source.getPhase());    return execution;  }}@Servicepublic class ArecoDeploymentScriptsRunner implements DeploymentScriptRunner {  private static final Logger LOG = Logger.getLogger(ArecoDeploymentScriptsRunner.class);  @Autowired  private ModelService modelService;(...)  private void saveAndLogScriptExecution(final UpdatingSystemExtensionContext context,      final ScriptExecutionModel scriptExecution) {    this.modelService.save(scriptExecution);                                                            // The model is stored into the database    context.logScriptExecutionResult(scriptExecution);  }} +@Component("deploymentScript2ExecutionConverter") 
-</code>+public class DeploymentScript2ExecutionConverter implements Converter<DeploymentScript, ScriptExecutionModel> { 
 +  private static final Logger LOG = Logger.getLogger(DeploymentScript2ExecutionConverter.class);
  
-To **retrieve** the model you may use ModelService#get(de.hybris.platform.core.PK) but you usually use Hybris Query Language **FlexibleSearch** to get items from the database.\\ You can **remove** an item using ModelService#remove(java.lang.Object).\\ You can **update the item with the contents of the database** using ModelService#refresh. If two thread modify simultaneously two instances of the same model containing different values, **the last thread is going to override the changes from the first one**. If you are updating critical models like stock levels you must do it inside a database transaction. Hybris don't have any optimistic locking mechanism like Hibernate ORM.+  @Autowired 
 +  private ModelService modelService;
  
-====== Localization of Hybris types and attributes ======+  /* 
 +   * (non-Javadoc) 
 +   *  
 +   * @see de.hybris.platform.servicelayer.dto.converter.Converter#convert(java.lang.Object) 
 +   */ 
 +  @Override 
 +  public ScriptExecutionModel convert(final DeploymentScript source) throws ConversionException { 
 +    return this.convert(source, (ScriptExecutionModel) this.modelService.create(ScriptExecutionModel.class)); // Creation of a new item 
 +  }
  
-The names and descriptions of the Hybris types, enumerations, relations and attributes can be localized using a property file inside **resources/localization**. For example,+  /* 
 +   (non-Javadoc) 
 +    
 +   @see de.hybris.platform.servicelayer.dto.converter.Converter#convert(java.lang.Objectjava.lang.Object) 
 +   */ 
 +  @Override 
 +  public ScriptExecutionModel convert(final DeploymentScript source, final ScriptExecutionModel execution) 
 +      throws ConversionException { 
 +    ServicesUtil.validateParameterNotNullStandardMessage("source", source); 
 +    ServicesUtil.validateParameterNotNullStandardMessage("execution", execution); 
 +    if (DeploymentScript2ExecutionConverter.LOG.isDebugEnabled()) { 
 +      DeploymentScript2ExecutionConverter.LOG.debug("Creating an script execution model from the deployment script " + source); 
 +    } 
 +    execution.setExtensionName(source.getExtensionName());                                                         // The model is filled 
 +    execution.setScriptName(source.getName()); 
 +    execution.setResult(null); // The caller must set the result before saving the execution. 
 +    execution.setPhase(source.getPhase());
  
-<code> +    return execution; 
-File arecoDeploymentScriptsManager/resources/localization/arecoDeploymentScriptsManager-locales_de.properties(...)type.DeploymentEnvironment.name=Deployment Umgebungentype.DeploymentEnvironment.name.name=Nametype.DeploymentEnvironment.description.name=Beschreibungtype.SystemPhase.name=Phase des Systemstype.SystemPhase.INITIALIZATION.name=Initializationtype.SystemPhase.UPDATE.name=Aktualisierung(...) +  }
-</code>+
  
-This sets the name of a Hybris type, an enumeration and two attributes in German.+}
  
-====== General Recommendations ======+@Service 
 +public class ArecoDeploymentScriptsRunner implements DeploymentScriptRunner {
  
-  * Please read [[https://wiki.hybris.com/display/hybrisALF/Type+System|Hybris' general good practices on defining types.]] Those recommendations aren't on this page+  private static final Logger LOG = Logger.getLogger(ArecoDeploymentScriptsRunner.class);
  
-  * Don't use the menu HMC > System > Types to modify the Hybris types on runtime because you changes will be lost after an update running system+  @Autowired 
 +  private ModelService modelService;
  
-\\ Based on Hybris 6.3+(...)
  
-<!-- +  private void saveAndLogScriptExecution(final UpdatingSystemExtensionContext context, 
-var jcomments=new JComments(64'com_content',%%'/%%component/jcomments%%/'%%); +      final ScriptExecutionModel scriptExecution) { 
-jcomments.setList%%('%%comments-list'); +    this.modelService.save(scriptExecution);                                                            // The model is stored into the database 
-%%//%%-->+    context.logScriptExecutionResult(scriptExecution); 
 +  } 
 +
 +</code>
  
 +To **retrieve** the model you may use ModelService#get(de.hybris.platform.core.PK) but you usually use Hybris Query Language **FlexibleSearch** to get items from the database.\\
 +You can **remove** an item using ModelService#remove(java.lang.Object).\\
 +You can **update the item with the contents of the database** using ModelService#refresh. If two thread modify simultaneously two instances of the same model containing different values, **the last thread is going to override the changes from the first one**. If you are updating critical models like stock levels you must do it inside a database transaction. Hybris don't have any optimistic locking mechanism like Hibernate ORM.
  
-=== Add comment ===+====== Localization of Hybris types and attributes ======
  
- Name (required)+The names and descriptions of the Hybris types, enumerations, relations and attributes can be localized using a property file inside **resources/localization**. For example,
  
- E-mail (required, but will not display)+<code> 
 +File arecoDeploymentScriptsManager/resources/localization/arecoDeploymentScriptsManager-locales_de.properties 
 +(...) 
 +type.DeploymentEnvironment.name=Deployment Umgebungen 
 +type.DeploymentEnvironment.name.name=Name 
 +type.DeploymentEnvironment.description.name=Beschreibung
  
- Website+type.SystemPhase.name=Phase des Systems 
 +type.SystemPhase.INITIALIZATION.name=Initialization 
 +type.SystemPhase.UPDATE.name=Aktualisierung 
 +(...) 
 +</code>
  
-{{:components:com_jcomments:images:smilies::laugh.gif|:D}}{{:components:com_jcomments:images:smilies::lol.gif|:lol:}}{{:components:com_jcomments:images:smilies::smile.gif|:-)}}{{:components:com_jcomments:images:smilies::wink.gif|;-)}}{{:components:com_jcomments:images:smilies::cool.gif|8)}}{{:components:com_jcomments:images:smilies::normal.gif|:-|}}{{:components:com_jcomments:images:smilies::whistling.gif|:-*}}{{:components:com_jcomments:images:smilies::redface.gif|:oops:}}{{:components:com_jcomments:images:smilies::sad.gif|:sad:}}{{:components:com_jcomments:images:smilies::cry.gif|:cry:}}{{:components:com_jcomments:images:smilies::surprised.gif|:o}}{{:components:com_jcomments:images:smilies::confused.gif|:-?}}{{:components:com_jcomments:images:smilies::sick.gif|:-x}}{{:components:com_jcomments:images:smilies::shocked.gif|:eek:}}{{:components:com_jcomments:images:smilies::sleeping.gif|:zzz}}{{:components:com_jcomments:images:smilies::tongue.gif|:P}}{{:components:com_jcomments:images:smilies::rolleyes.gif|:roll:}}{{:components:com_jcomments:images:smilies::unsure.gif|:sigh:}}1000 symbols left +This sets the name of a Hybris type, an enumeration and two attributes in German.
- +
- Notify me of follow-up comments\\ +
  
-[[#|Send]] +====== General Recommendations ====== 
- +  * Please read [[https://www.sap.com/cxworks/article/433893244/Data_Model_Design_with_the_SAP_Commerce_Cloud_Type_System|Hybris' general good practices on defining types.]] Those recommendations aren't on this page 
-[[#|Cancel]] +  * Don't use the menu Backoffice > System > Types to modify the Hybris types on runtime because you changes will be lost after an update running system
- +
-  +
- +
-<!-- +
-function JCommentsInitializeForm() +
-+
-        var jcEditor new JCommentsEditor%%('%%comments-form-comment', true); +
-        jcEditor.initSmiles%%('/%%components/com_jcomments/images/smilies%%/'%%); +
-        jcEditor.addSmile%%('%%:D','laugh.gif'); +
-        jcEditor.addSmile%%('%%:lol:','lol.gif'); +
-        jcEditor.addSmile%%('%%:-)','smile.gif'); +
-        jcEditor.addSmile%%('%%;-)','wink.gif'); +
-        jcEditor.addSmile%%('%%8)','cool.gif'); +
-        jcEditor.addSmile%%('%%:-|','normal.gif'); +
-        jcEditor.addSmile%%('%%:-%%*'%%,'whistling.gif'); +
-        jcEditor.addSmile%%('%%:oops:','redface.gif'); +
-        jcEditor.addSmile%%('%%:sad:','sad.gif'); +
-        jcEditor.addSmile%%('%%:cry:','cry.gif'); +
-        jcEditor.addSmile%%('%%:o','surprised.gif'); +
-        jcEditor.addSmile%%('%%:-?','confused.gif'); +
-        jcEditor.addSmile%%('%%:-x','sick.gif'); +
-        jcEditor.addSmile%%('%%:eek:','shocked.gif'); +
-        jcEditor.addSmile%%('%%:zzz','sleeping.gif'); +
-        jcEditor.addSmile%%('%%:P','tongue.gif'); +
-        jcEditor.addSmile%%('%%:roll:','rolleyes.gif'); +
-        jcEditor.addSmile%%('%%:sigh:','unsure.gif'); +
-        jcEditor.addCounter(1000, %%''%%, ' symbols left', 'counter'); +
-        jcomments.setForm(new JCommentsForm%%('%%comments-form', jcEditor)); +
-+
- +
-if (window.addEventListener) {window.addEventListener%%('%%load',JCommentsInitializeForm,false);+
-else if (document.addEventListener){document.addEventListener%%('%%load',JCommentsInitializeForm,false);+
-else if (window.attachEvent){window.attachEvent%%('%%onload',JCommentsInitializeForm);+
-else {if (typeof window.onload=='function'){var oldload=window.onload;window.onload=function(){oldload();JCommentsInitializeForm();}} else window.onload=JCommentsInitializeForm;}  +
-%%//%%--> +
- +
- +
-[[http://www.joomlatune.com|JComments]]+
  
-  * You are here:   +--Based on Hybris 6.5
-  * [[:|Home]] {{:media:system:images:arrow.png}}  +
-  * Hybris' persistence mechanism+