Performance Improvements

Objective

After completing this lesson, you will be able to examine Performance Improvements in SAP Commerce Cloud

Disabling FlexibleSearch Restrictions for Individual Users

To improve performance, it's now possible to globally disable FlexibleSearch restrictions defined for individual users, keeping only user group restrictions instead, or further disable them for users in selected user groups.

You can now globally disable FlexibleSearch restrictions defined for individual users and only keep the group restrictions by using the following property:

JSON
1
flexible.search.disable.individual.search.restrictions=true

The default value of this property is false. Since FlexibleSearch restrictions are usually defined for user groups, disabling individual user restrictions doesn't affect query results, but it improves performance by reducing the number of required database calls.

Caution

We don't recommend using this property if you've created different FlexibleSearch restrictions for specific users. Applying this property in such a configuration would disable all the individual restrictions.

To further disable individual FlexibleSearch restriction for users in selected user groups, use the following property:

JSON
12
flexible.search.disable.individual.search.restrictions.for.members.of=customergroup,employeegroup

The flexible.search.disable.individual.search.restrictions.for.members.of property can only be used if flexible.search.disable.individual.search.restrictions is set to true. The value of this property should be a comma-separated list of group IDs.

If you don't specify any user groups as a value of this property, individual search restrictions will be disabled for all users.

Why?

Reduced number of database calls improves the performance of SAP Commerce Cloud.

Improved Performance for Accessing Quote Information

Give your customers a smoother experience when accessing quote information by reducing unnecessary database calls. This optimization helps when customers retrieve lists of quotes.

Previously, when customers accessed quote information, the default QuotePopulator was used. This method, which fully populates every quote, can be inefficient and costly, especially in B2B contexts. It also generates a large number of database queries. To reduce unnecessary database calls and enhance the user experience, four toggles are introduced:

  • The toggle toggle.quotePopulatorSkipHasCart.enabled is added to de.hybris.platform.commercefacades.constants.CommerceFacadesConstants under the commercefacades extension. It skips populating the hasCart field while generating QuoteData.
  • The toggle toggle.quotePopulatorSkipOrderCode.enabled is added to de.hybris.platform.commercefacades.constants.CommerceFacadesConstants under the commercefacades extension. It skips populating the orderCode field.
  • The toggle toggle.quoteHelperSkipRetrieveCartReference.enabled is added to de.hybris.platform.b2bocc.constants.B2boccConstants under the b2bocc extension. It skips retrieving the cartReference again in QuoteHelper.
  • The toggle toggle.findOrderByUserAndQuoteReference.enabled is added to de.hybris.platform.commerceservices.constants.CommerceServicesConstants under the commerceservices extension. It uses both the customer information and quoteReference to retrieve an order instead of using quoteReference only.

Why?

This enhancement improves user experience and system efficiency, especially in B2B environments.

Enhanced Cart Removal Cronjob to Delete Expired Saved Carts

The enhanced cart removal cronjob now deletes expired saved carts, preventing them from being restored as session carts.

The cart removal cronjob deletes expired saved carts directly instead of restoring them as session carts. To enable the deletion, a toggle named toggle.expiredSavedCartDeletion.enabled is add to the project.properties under acceleratorservices.

Why?

This feature improves customer satisfaction by ensuring outdated carts don't clutter user sessions, streamlining the shopping experience.

Improved Orphan Removal for Many-to-Many Relationship Management in ServiceLayer Direct Mode

Orphan removal in many-to-many relations for ServiceLayer Direct (SLD) mode has been improved, ensuring updates only retain current relationships and keep your data consistent.

Why?

With this improvement, you no longer have to worry about unwanted associations that can lead to inconsistent data. This improved behavior helps maintain clean, accurate relationship management, reducing risks in data integrity and simplifying model updates in day-to-day operations.

What's Changed?

This behavior applies only when managing many-to-many relations in SLD mode under the condition that existing relationships are updated within the same save operation.

When the same relation was modified from both sides within one save operation, the existing mechanism only checked for existing connections from one direction. Under certain circumstances, during an update operation, old connections between the modified source and target were not removed, leading to an inconsistent final state.

Here's an example of incorrect behavior:

Java
123456789101112131415161718192021222324
PersistenceUtils.doWithSLDPersistence { //Assume we have correctly created two categories final CategoryModel categoryA = createCategory() final CategoryModel categoryB = createCategory() //Assume we have correctly created product final ProductModel product = getProduct() //Assign product to categoryA product.setSupercategories(Collections.singletonList(categoryA)); categoryA.setProducts(Collections.singletonList(product)); modelService.saveAll(categoryA, product); //Update assignment and replace categoryA with categoryB from both sides of relation product.setSupercategories(Collections.singletonList(categoryB)); categoryB.setProducts(Collections.singletonList(product)); modelService.saveAll(categoryB, product); //Expected: //product.getSupercategories() -> [categoryB] //Returned //product.getSupercategories() -> [categoryA, categoryB] }

Under expected behavior, a product should have a many-to-many relationship only with categoryB. However, due to an issue with the persistence logic, a product ended up containing relationships with both categoryA and categoryB.

During the update process for product-level relationships, if existing relationships needed to be removed, the query only checked one side of the relationship. By failing to consider both directions, it resulted in an inconsistent state where old relationships were not properly removed.

This affected both localized and non-localized many-to-many relations. Notably, if a relation was modified from one side only during a single save operation, no issue occurred.

Solution

The mechanism responsible for updating relationships now correctly checks relationships from both the source and target sides if needed. This behavior ensures the proper removal of outdated connections. It's worth noting that for such a case, managing the relation change from only one side would be more optimal, as shown in the example.